blob: b8a396bc4a62cf7c3eb79e62b6798f6d8434558e [file] [log] [blame]
/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for license information.
*--------------------------------------------------------*/
'use strict';
import cp = require('child_process');
import { dirname, isAbsolute } from 'path';
import vscode = require('vscode');
import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
import { getBinPath } from './util';
/**
* Extracts function out of current selection and replaces the current selection with a call to the extracted function.
*/
export function extractFunction() {
extract('extract');
}
/**
* 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() {
extract('var');
}
type typeOfExtraction = 'var' | 'extract';
async function extract(type: typeOfExtraction): Promise<void> {
const 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 ${type === 'var' ? 'variable' : 'method'}`
);
return;
}
const newName = await vscode.window.showInputBox({
placeHolder: `Please enter a name for the extracted ${type === 'var' ? 'variable' : 'method'}.`
});
if (!newName) {
return;
}
runGoDoctor(newName, activeEditor.selection, activeEditor.document.fileName, type);
}
/**
* @param newName 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
*/
function runGoDoctor(
newName: string,
selection: vscode.Selection,
fileName: string,
type: typeOfExtraction
): Thenable<void> {
const godoctor = getBinPath('godoctor');
return new Promise((resolve, reject) => {
if (!isAbsolute(godoctor)) {
promptForMissingTool('godoctor');
return resolve();
}
cp.execFile(
godoctor,
[
'-w',
'-pos',
`${selection.start.line + 1},${selection.start.character + 1}:${selection.end.line + 1},${
selection.end.character
}`,
'-file',
fileName,
type,
newName
],
{
env: toolExecutionEnvironment(),
cwd: dirname(fileName)
},
(err, stdout, stderr) => {
if (err) {
vscode.window.showErrorMessage(stderr || err.message);
}
}
);
});
}