Skip to content

Commit

Permalink
Add extract to var command and code action
Browse files Browse the repository at this point in the history
  • Loading branch information
aswinmprabhu committed Nov 21, 2018
1 parent 61a8230 commit 1654d62
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 52 deletions.
151 changes: 107 additions & 44 deletions src/goDoctor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,58 +16,121 @@ import { resolve } from 'dns';
* Extracts function out of current selection and replaces the current selection with a call to the extracted function.
*/
export function extractFunction() {
let activeEditor = vscode.window.activeTextEditor;
if (!activeEditor) {
vscode.window.showInformationMessage('No editor is active.');
return;
}
if (activeEditor.selections.length !== 1) {
vscode.window.showInformationMessage('You need to have a single selection for extracting method');
return;
}
let showInputBoxPromise = vscode.window.showInputBox({ placeHolder: 'Plese enter a name for the extracted function.' });
showInputBoxPromise.then((functionName: string) => {
runGoDoctorExtract(functionName, activeEditor.selection, activeEditor).then(errorMessage => {
if (errorMessage) {
vscode.window.showErrorMessage(errorMessage);
}
});
});
let activeEditor = vscode.window.activeTextEditor;
if (!activeEditor) {
vscode.window.showInformationMessage('No editor is active.');
return;
}
if (activeEditor.selections.length !== 1) {
vscode.window.showInformationMessage('You need to have a single selection for extracting method');
return;
}
let showInputBoxPromise = vscode.window.showInputBox({ placeHolder: 'Plese enter a name for the extracted function.' });
showInputBoxPromise.then((functionName: string) => {
runGoDoctorExtract(functionName, activeEditor.selection, activeEditor).then(errorMessage => {
if (errorMessage) {
vscode.window.showErrorMessage(errorMessage);
}
});
});
}

/**
* Extracts expression out of current selection into a var in the local scope and
* replaces the current selection with the new var.
*/
export function extractVariable() {
let activeEditor = vscode.window.activeTextEditor;
if (!activeEditor) {
vscode.window.showInformationMessage('No editor is active.');
return;
}
if (activeEditor.selections.length !== 1) {
vscode.window.showInformationMessage('You need to have a single selection for extracting method');
return;
}
let showInputBoxPromise = vscode.window.showInputBox({ placeHolder: 'Plese enter a name for the extracted variable.' });
showInputBoxPromise.then((varName: string) => {
runGoDoctorVar(varName, activeEditor.selection, activeEditor).then(errorMessage => {
if (errorMessage) {
vscode.window.showErrorMessage(errorMessage);
}
});
});
}

/**
* @param functionName name for the extracted method
* @param selection the editor selection from which method is to be extracted
* @param activeEditor the editor that will be used to apply the changes from godoctor
* @returns errorMessage in case the method fails, null otherwise
*/
export function runGoDoctorExtract(functionName: string, selection: vscode.Selection, activeEditor: vscode.TextEditor): Thenable<string> {
let godoctor = getBinPath('godoctor');
let godoctor = getBinPath('godoctor');

return new Promise((resolve, reject) => {
if (typeof functionName === 'undefined') {
return resolve('Function Name is undefined');
}
let args = [
'-w',
'-pos',
`${selection.start.line + 1},${selection.start.character + 1}:${selection.end.line + 1},${selection.end.character + 1}`,
'-file',
activeEditor.document.fileName,
'extract',
functionName,
];
let p = cp.execFile(godoctor, args, { env: getToolsEnvVars(), cwd: dirname(activeEditor.document.fileName) }, (err, stdout, stderr) => {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('godoctor');
return resolve('Could not find godoctor');
}
if (err) {
return resolve(`Could not extract function : \n\n${stderr}`);
}
});
if (p.pid) {
p.stdin.end();
}

});
}

/**
* @param varName name for the extracted method
* @param selection the editor selection from which method is to be extracted
* @param activeEditor the editor that will be used to apply the changes from godoctor
* @returns errorMessage in case the method fails, null otherwise
*/
export function runGoDoctorVar(varName: string, selection: vscode.Selection, activeEditor: vscode.TextEditor): Thenable<string> {
let godoctor = getBinPath('godoctor');

return new Promise((resolve, reject) => {
if (typeof functionName === 'undefined') {
return resolve('Function Name is undefined');
}
let args = [
'-w',
'-pos',
`${selection.start.line + 1},${selection.start.character + 1}:${selection.end.line + 1},${selection.end.character + 1}`,
'-file',
activeEditor.document.fileName,
'extract',
functionName,
];
let p = cp.execFile(godoctor, args, { env: getToolsEnvVars(), cwd: dirname(activeEditor.document.fileName) }, (err, stdout, stderr) => {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('godoctor');
return resolve('Could not find godoctor');
}
if (err) {
return resolve(`Could not extract function : \n\n${stderr}`);
}
});
if (p.pid) {
p.stdin.end();
}
return new Promise((resolve, reject) => {
if (typeof varName === 'undefined') {
return resolve('Function Name is undefined');
}
let args = [
'-w',
'-pos',
`${selection.start.line + 1},${selection.start.character + 1}:${selection.end.line + 1},${selection.end.character + 1}`,
'-file',
activeEditor.document.fileName,
'var',
varName,
];
let p = cp.execFile(godoctor, args, { env: getToolsEnvVars(), cwd: dirname(activeEditor.document.fileName) }, (err, stdout, stderr) => {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('godoctor');
return resolve('Could not find godoctor');
}
if (err) {
return resolve(`Could not extract variable : \n\n${stderr}`);
}
});
if (p.pid) {
p.stdin.end();
}

});
});
}
5 changes: 4 additions & 1 deletion src/goMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { runFillStruct } from './goFillStruct';
import { parseLiveFile } from './goLiveErrors';
import { GoReferencesCodeLensProvider } from './goReferencesCodelens';
import { implCursor } from './goImpl';
import { extractFunction } from './goDoctor';
import { extractFunction, extractVariable } from './goDoctor';
import { browsePackages } from './goBrowsePackage';
import { goGetPackage } from './goGetPackage';
import { GoDebugConfigurationProvider } from './goDebugConfiguration';
Expand Down Expand Up @@ -242,6 +242,9 @@ export function activate(ctx: vscode.ExtensionContext): void {
ctx.subscriptions.push(vscode.commands.registerCommand('go.godoctor.extract', () => {
extractFunction();
}));
ctx.subscriptions.push(vscode.commands.registerCommand('go.godoctor.var', () => {
extractVariable();
}));

ctx.subscriptions.push(vscode.commands.registerCommand('go.test.cursor', (args) => {
let goConfig = vscode.workspace.getConfiguration('go', vscode.window.activeTextEditor ? vscode.window.activeTextEditor.document.uri : null);
Expand Down
18 changes: 11 additions & 7 deletions src/goRefactor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,22 @@ import vscode = require('vscode');
export class GoRefactorProvider implements vscode.CodeActionProvider {
public provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken): vscode.ProviderResult<vscode.CodeAction[]> {
const extractFunction = new vscode.CodeAction(
'Extract Function',
'Extract to function in package scope',
vscode.CodeActionKind.RefactorExtract
);
const extractVar = new vscode.CodeAction(
'Extract to variable in local scope',
vscode.CodeActionKind.RefactorExtract
);
extractFunction.command = {
title: 'Extract Function',
title: '',
command: 'go.godoctor.extract',
arguments: [
document,
range,
],
};
extractVar.command = {
title: 'Extract to variable in local scope',
command: 'go.godoctor.var',
};

return [extractFunction];
return [extractFunction, extractVar];
}
}

0 comments on commit 1654d62

Please sign in to comment.