-
-
Notifications
You must be signed in to change notification settings - Fork 247
Adds Various code actions to make refactoring a bit easier #853
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
DaviD4Chirino
wants to merge
35
commits into
godotengine:master
Choose a base branch
from
DaviD4Chirino:extract-code-as-a-variable
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
74ec33c
registered a test refractor
DaviD4Chirino b6e74da
added addRangeExportToVariable
DaviD4Chirino 4601163
tried and failed to make a snippet
DaviD4Chirino c524864
added export these variables
DaviD4Chirino 49dca75
addRangeExportToVariable now discerns between a float and a int
DaviD4Chirino 4da75dd
added todo
DaviD4Chirino 108b6a0
refractored a bit
DaviD4Chirino faa2517
added documentation to one
DaviD4Chirino 6103431
tempted to make exportColorNoAlpha
DaviD4Chirino 6f0f710
Merge pull request #1 from DaviD4Chirino/refractoring-variables-exports
DaviD4Chirino 33ee201
added mockup refractor
DaviD4Chirino 088f414
added refractor command
DaviD4Chirino 99fe57f
moved the command to where all the other commands are
DaviD4Chirino 515502a
handleDifferentTypedVariableExports was messing with everything, removed
DaviD4Chirino d2dc733
added extract as a function
DaviD4Chirino 21a46ed
Merge pull request #2 from DaviD4Chirino/extract-code-to-its-own-func…
DaviD4Chirino 7d486e8
added command
DaviD4Chirino ac09538
added extract_variable command
DaviD4Chirino ec1eb3a
added newline to extract_function and added codeAction to extract var…
DaviD4Chirino 9dc473f
added tabString to utils
DaviD4Chirino e548dcd
preparing to test my own branch
DaviD4Chirino 09ce9cb
bumped the version
DaviD4Chirino 04ccfe9
updated the readme and downstreamed the version
DaviD4Chirino 18d019f
added missing semi colons
DaviD4Chirino 4f073dd
added another missing semicolon
DaviD4Chirino 49be85d
added missing semi colons
DaviD4Chirino da18c04
addressed most comments
DaviD4Chirino d42be3b
removed "unnecessary" types
DaviD4Chirino 6559405
made the requested changes, and fixed a bug
DaviD4Chirino f7d172b
Registered code action provider into providers
DaviD4Chirino 1c69c3f
Fix linter complaints
DaelonSuzuka cd5083c
Format and fix lint errors
DaelonSuzuka f4ea9fc
reworked extract function to not require external commands
DaviD4Chirino 721158c
reworked extractVariable
DaviD4Chirino ca0f061
removed extractFunction and extractVariable commands
DaviD4Chirino File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -920,4 +920,4 @@ | |
| "ws": "^8.17.1", | ||
| "ya-bbcode": "^4.0.0" | ||
| } | ||
| } | ||
| } | ||
|
DaelonSuzuka marked this conversation as resolved.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,274 @@ | ||
| import * as vscode from "vscode"; | ||
| import { | ||
| ExtensionContext | ||
| } from "vscode"; | ||
| import { tabString } from "../utils"; | ||
| /** | ||
| * @param $1 The variable name (including the : if it has it), | ||
| * @param $2 The variable type, | ||
| * @param $3 Everything else after the type | ||
| */ | ||
| const VARIABLE_REGEXP: RegExp = /^var\s*(\w+:?)\s*\s*(\w*)([\s\S\w\W]*)/; | ||
|
|
||
| export class GDCodeActionProvider implements vscode.CodeActionProvider { | ||
| constructor(private context: ExtensionContext) { | ||
| context.subscriptions.push( | ||
| vscode.languages.registerCodeActionsProvider( | ||
| { language: 'gdscript' }, | ||
| this, | ||
| { | ||
| providedCodeActionKinds: GDCodeActionProvider.providedCodeActionKinds, | ||
| } | ||
| ) | ||
| ); | ||
|
|
||
| } | ||
| // Define the kind of code actions this provider offers | ||
| public static readonly providedCodeActionKinds = [ | ||
| vscode.CodeActionKind.Refactor, | ||
| vscode.CodeActionKind.RefactorExtract, | ||
| vscode.CodeActionKind.RefactorRewrite, | ||
| vscode.CodeActionKind.RefactorInline, | ||
| ]; | ||
|
|
||
| public provideCodeActions( | ||
| document: vscode.TextDocument, | ||
| range: vscode.Range, | ||
| context: vscode.CodeActionContext, | ||
| token: vscode.CancellationToken | ||
| ): vscode.ProviderResult<vscode.CodeAction[]> { | ||
|
|
||
| // Specify the edits to be applied | ||
| const _exportTheseVariables = exportTheseVariables(document); | ||
| const _extractFunction = extractFunction(document); | ||
| const _extractVariable = extractVariable(document); | ||
|
|
||
| const _addExportToVariable = addExportToVariable(range, document); | ||
| const _addRangeExportToVariable = addRangeExportToVariable(range, document); | ||
|
|
||
| return [_extractVariable, _extractFunction, _exportTheseVariables, _addExportToVariable, _addRangeExportToVariable]; | ||
| } | ||
|
|
||
|
|
||
| } | ||
|
|
||
|
|
||
|
|
||
| function addExportToVariable(range: vscode.Range, document: vscode.TextDocument): vscode.CodeAction { | ||
| const startLine = document.lineAt(range.start.line); | ||
| const lineText = startLine.text; | ||
|
|
||
| const exec: RegExpExecArray | null = VARIABLE_REGEXP.exec(lineText); | ||
| if (!exec) { | ||
| return undefined; | ||
| } | ||
|
|
||
| const codeAction = new vscode.CodeAction( | ||
| "Export this variable", | ||
| vscode.CodeActionKind.RefactorInline | ||
| ); | ||
|
|
||
|
|
||
| codeAction.edit = new vscode.WorkspaceEdit(); | ||
|
|
||
| const updatedText = lineText.replace(VARIABLE_REGEXP, "@export var $1 $2 $3"); | ||
|
|
||
| codeAction.edit.replace( | ||
| document.uri, | ||
| startLine.range, | ||
| updatedText | ||
| ); | ||
|
|
||
| return codeAction; | ||
| } | ||
|
|
||
| function addRangeExportToVariable(range: vscode.Range, document: vscode.TextDocument): vscode.CodeAction { | ||
| const startLine = document.lineAt(range.start.line); | ||
| const lineText = startLine.text.trim(); | ||
|
|
||
| const exec: RegExpExecArray | null = VARIABLE_REGEXP.exec(lineText); | ||
| if (!exec) { | ||
| return undefined; | ||
| } | ||
|
|
||
| const [_, name, type, body] = exec; | ||
|
|
||
| const is_number = type.trim() === "float" || type.trim() === "int"; | ||
| if (!is_number) return undefined; | ||
|
|
||
| const codeAction = new vscode.CodeAction( | ||
| "Export as a range", | ||
| vscode.CodeActionKind.RefactorInline | ||
| ); | ||
|
|
||
| codeAction.edit = new vscode.WorkspaceEdit(); | ||
| let updatedText = ""; | ||
|
|
||
| if (type.trim() === "float") { | ||
| updatedText = lineText.replace(VARIABLE_REGEXP, `@export_range(0.0, 1.0) var ${name} ${type} ${body}`); | ||
| } else { | ||
| updatedText = lineText.replace(VARIABLE_REGEXP, `@export_range(0, 1) var ${name} ${type} ${body}`); | ||
| } | ||
|
|
||
| codeAction.edit.replace( | ||
| document.uri, | ||
| startLine.range, | ||
| updatedText | ||
| ); | ||
| codeAction.isPreferred = true; | ||
| return codeAction; | ||
| } | ||
|
|
||
| function extractVariable(document: vscode.TextDocument) { | ||
| const editor = vscode.window.activeTextEditor; | ||
| if (!editor) return undefined; | ||
| const selectedText = document.getText(editor.selection); | ||
| if (selectedText === "") return undefined; | ||
| const codeAction = new vscode.CodeAction( | ||
| "Extract Variable", | ||
| vscode.CodeActionKind.RefactorExtract, | ||
| ); | ||
|
|
||
| const variableName = "_new_variable_name"; | ||
|
|
||
| const pasteLine: number = editor.selection.start.line; | ||
|
|
||
| /** Paste at the same indentation level, just above the selection */ | ||
| let indentation = ""; | ||
|
|
||
| /** Look for the whitespace above at the start of the line */ | ||
| const exec = /^\s+/.exec(document.lineAt(pasteLine).text); | ||
| if (exec) { | ||
| indentation = exec[0]; | ||
| } | ||
|
|
||
| //\t\t var xyz := x + y + z\n | ||
| const newVariable = new vscode.SnippetString(`${indentation}var ${variableName}$0 := ${selectedText}\n`); | ||
|
|
||
| const position = new vscode.Position(document.lineAt(pasteLine).lineNumber, 0); | ||
|
|
||
| const referenceNewVariable = vscode.TextEdit.replace( | ||
| editor.selection, | ||
| variableName | ||
| ); | ||
| const insertNewFunction = vscode.SnippetTextEdit.insert( | ||
| position, | ||
| newVariable | ||
| ); | ||
|
|
||
| const edit = new vscode.WorkspaceEdit(); | ||
|
|
||
| edit.set(document.uri, [ | ||
| referenceNewVariable, | ||
| insertNewFunction | ||
| ]); | ||
| codeAction.edit = edit; | ||
| codeAction.command = { | ||
| command: "editor.action.rename", | ||
| title: "Rename the new variable" | ||
| }; | ||
|
|
||
| return codeAction; | ||
| } | ||
|
|
||
| function extractFunction(document: vscode.TextDocument) { | ||
| const editor = vscode.window.activeTextEditor; | ||
| if (!editor) return undefined; | ||
| const selectedText = document.getText(editor.selection); | ||
| if (selectedText === "") return undefined; | ||
| const codeAction = new vscode.CodeAction( | ||
| "Extract function", | ||
| vscode.CodeActionKind.RefactorExtract, | ||
| ); | ||
| const tabOrSpace = tabString(); | ||
| // TODO: Maybe look for another name because if by any chance the user has this exact function name, it will mess things up | ||
| const functionName = "_new_function"; | ||
| const newFunction: string = `func ${functionName}():\n${selectedText | ||
| .split("\n") | ||
| .map((line) => tabOrSpace + line) | ||
| .join("\n")}\n`; | ||
| /** | ||
| * Look in each line, starting with this one and go down, | ||
| * if you find a line with a method declaration, go up one and paste the new function | ||
| * or the end of the document | ||
| */ | ||
| let pasteLine: number = editor.selection.end.line; | ||
|
|
||
| for (let i = 0; i < document.lineCount; i++) { | ||
| if (i < pasteLine) continue; | ||
| const textLine = document.lineAt(i); | ||
|
|
||
| if (textLine.text.startsWith("func")) { | ||
| break; | ||
| } else { | ||
| pasteLine++; | ||
| } | ||
| } | ||
| const position = new vscode.Position(Math.min(pasteLine, document.lineCount), 0); | ||
|
|
||
| const edit = new vscode.WorkspaceEdit(); | ||
|
|
||
| const callNewFunction = vscode.SnippetTextEdit.replace( | ||
| editor.selection, | ||
| new vscode.SnippetString(`${functionName}$0()`) | ||
| ); | ||
| const insertNewFunction = vscode.TextEdit.insert( | ||
| position, `\n${newFunction}` | ||
| ); | ||
|
|
||
| edit.set(document.uri, [ | ||
| callNewFunction, | ||
| insertNewFunction | ||
| ]); | ||
|
|
||
| codeAction.edit = edit; | ||
|
|
||
| codeAction.command = { | ||
| command: "editor.action.rename", | ||
| title: "Rename the new function" | ||
| }; | ||
|
|
||
| return codeAction; | ||
| } | ||
|
|
||
| // TODO: When everything is done, this should export them to their designated exports | ||
| function exportTheseVariables(document: vscode.TextDocument): vscode.CodeAction { | ||
| const codeAction = new vscode.CodeAction( | ||
| "Export these variables", | ||
| vscode.CodeActionKind.RefactorRewrite, | ||
| ); | ||
| const editor = vscode.window.activeTextEditor; | ||
| const selectedText = document.getText(editor.selection); | ||
|
|
||
| if (selectedText === "") return undefined; | ||
|
|
||
| const individualLines = selectedText.split("\n"); | ||
|
|
||
| let updatedText: string[] = []; | ||
| let nonVarElements = 0; | ||
| let varElements = 0; | ||
|
|
||
| for (let i = 0; i < individualLines.length; i++) { | ||
| const element = individualLines[i]; | ||
|
|
||
| if (!element.startsWith("var ")) { | ||
| updatedText = updatedText.concat(element); | ||
| nonVarElements++; | ||
| continue; | ||
| } | ||
| updatedText = updatedText.concat(element.replace(/^var/, "@export var")); | ||
| varElements++; | ||
| } | ||
|
|
||
| if (varElements < 1) return undefined; | ||
|
|
||
| const newText: string = updatedText.join("\n"); | ||
| codeAction.edit = new vscode.WorkspaceEdit(); | ||
| codeAction.edit.replace( | ||
| document.uri, | ||
| editor.selection, | ||
| newText, | ||
| ); | ||
| codeAction.isPreferred = true; | ||
| return codeAction; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| var simple_export | ||
| var range_export: float = 0.0 | ||
| var range_export_integer: int = 0 | ||
| var range_export_integer: int | ||
| var range_export_float: float | ||
|
|
||
| var ex | ||
| var ex | ||
| const ex | ||
| var ex | ||
| var ex | ||
|
|
||
|
|
||
| func export_code_as_new_function(args): | ||
| if condition: | ||
| var a | ||
| var b | ||
| var c | ||
| else: | ||
| pass | ||
| pass | ||
| pass | ||
| if condition: | ||
| if condition: | ||
| if condition: | ||
| pass | ||
| func method(args): | ||
| position.x += (15 / 2) * 5 | ||
| var lambda = func (x): | ||
| print(x) | ||
| pass | ||
|
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.