Add command to fetch import on current line (#1222)
* Add command to fetch import on current line This will allow users to easily fetch a dependency without having to take their attention away from the code they're editing. Microsoft/vscode-go#1189 * Rename goGetImports to goGetImport The plugin only fetches one import so having the file name plural is misleading to anybody reading the code. Microsoft/vscode-go#1189 * Refactor getImportPath This consolidates the functionality found in two commands into one place so that if it ever needs to be changed or removed it can be done more easily. * Fix lint issues * Make command title and description more intuitive Microsoft/vscode-go#1189 * Make name `goGetPackage` consistent Anybody else who comes along later and reads this is gonna have an easier time if they only have to keep one name in their head vs. having to keep two (goGetImport and goGetPackage). Microsoft/vscode-go#1189 * Exit early if there's no import path to get If there's no import path to pass to `go get` then there's no point in spinning up a child process and waiting for it to finish to error out. This also fixes a bug in `getImportPath` that would cause it to return invalid input paths for things like comments and function definitions. Microsoft/vscode-go#1189 * Fallback to selectedText for browsePackage feature * Offload check for package to go get `go get` won't download a package if it's already in `$GOPATH/src`. There's no point in checking for the package to exist and then downloading with `-u` because `go get -u` and `go get` are effectively the same when a package hasn't been downloaded yet. Microsoft/vscode-go#1189 * Use output pane for go get output `go get -v` gives users more information on what's going on with the command. This way a user can tell if the package was even downloaded, because by default `go get` won't output anything. `go get -v` will output nothing if the package isn't downloaded because it already exists. To get around this, an information message is shown saying that the package wasn't downloaded. This keeps the user informed because they will be expecting feedback from the command. In the event of an error (like if there's no internet connection), the error gets shown to the output pane so the user knows what happened. Microsoft/vscode-go#1189 * Cleanup
This commit is contained in:
Родитель
e2175a303e
Коммит
2e2e3cda2b
|
@ -169,6 +169,11 @@
|
|||
"command": "go.browse.packages",
|
||||
"title": "Go: Browse Packages",
|
||||
"description": "Browse packages and Go files inside the packages."
|
||||
},
|
||||
{
|
||||
"command": "go.get.package",
|
||||
"title": "Go: Get Package",
|
||||
"description": "Run `go get -v` on the package on the current line."
|
||||
}
|
||||
],
|
||||
"debuggers": [
|
||||
|
|
|
@ -10,6 +10,7 @@ import cp = require('child_process');
|
|||
import { getGoRuntimePath } from './goPath';
|
||||
import path = require('path');
|
||||
import { getAllPackages } from './goPackages';
|
||||
import { getImportPath } from './util';
|
||||
|
||||
export function browsePackages() {
|
||||
let selectedText = '';
|
||||
|
@ -23,7 +24,7 @@ export function browsePackages() {
|
|||
// if selection is empty, then get the whole line the cursor is currently on.
|
||||
selectedText = editor.document.lineAt(selection.active.line).text;
|
||||
}
|
||||
selectedText = getImportPath(selectedText);
|
||||
selectedText = getImportPath(selectedText) || selectedText.trim();
|
||||
}
|
||||
|
||||
showPackageFiles(selectedText, true);
|
||||
|
@ -85,19 +86,3 @@ function showPackageList() {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getImportPath(text: string): string {
|
||||
// Catch cases like `import alias "importpath"` and `import "importpath"`
|
||||
let singleLineImportMatches = text.match(/^\s*import\s+([a-z,A-Z,_,\.]\w*\s+)?\"([^\"]+)\"/);
|
||||
if (singleLineImportMatches) {
|
||||
return singleLineImportMatches[2];
|
||||
}
|
||||
|
||||
// Catch cases like `alias "importpath"` and "importpath"
|
||||
let groupImportMatches = text.match(/^\s*([a-z,A-Z,_,\.]\w*\s+)?\"([^\"]+)\"/);
|
||||
if (groupImportMatches) {
|
||||
return groupImportMatches[2];
|
||||
}
|
||||
|
||||
return text.trim();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
'use strict';
|
||||
|
||||
import vscode = require('vscode');
|
||||
import cp = require('child_process');
|
||||
import { getGoRuntimePath } from './goPath';
|
||||
import { getImportPath } from './util';
|
||||
import { outputChannel } from './goStatus';
|
||||
|
||||
export function goGetPackage() {
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
const selection = editor.selection;
|
||||
const selectedText = editor.document.lineAt(selection.active.line).text;
|
||||
|
||||
const importPath = getImportPath(selectedText);
|
||||
if (importPath === '') {
|
||||
vscode.window.showErrorMessage('No import path to get');
|
||||
return;
|
||||
}
|
||||
|
||||
const goRuntimePath = getGoRuntimePath();
|
||||
if (!goRuntimePath) {
|
||||
return vscode.window.showErrorMessage('Could not locate Go binaries. Make sure you have Go installed');
|
||||
}
|
||||
|
||||
cp.execFile(goRuntimePath, ['get', '-v', importPath], (err, stdout, stderr) => {
|
||||
// go get -v uses stderr to write output regardless of success or failure
|
||||
if (stderr !== '') {
|
||||
outputChannel.show();
|
||||
outputChannel.clear();
|
||||
outputChannel.appendLine(stderr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// go get -v doesn't write anything when the package already exists
|
||||
vscode.window.showInformationMessage(`Package already exists: ${importPath}`);
|
||||
});
|
||||
};
|
|
@ -37,6 +37,7 @@ import { parseLiveFile } from './goLiveErrors';
|
|||
import { GoReferencesCodeLensProvider } from './goReferencesCodelens';
|
||||
import { implCursor } from './goImpl';
|
||||
import { browsePackages } from './goBrowsePackage';
|
||||
import { goGetPackage } from './goGetPackage';
|
||||
|
||||
export let errorDiagnosticCollection: vscode.DiagnosticCollection;
|
||||
let warningDiagnosticCollection: vscode.DiagnosticCollection;
|
||||
|
@ -283,6 +284,8 @@ export function activate(ctx: vscode.ExtensionContext): void {
|
|||
});
|
||||
}));
|
||||
|
||||
ctx.subscriptions.push(vscode.commands.registerCommand('go.get.package', goGetPackage));
|
||||
|
||||
vscode.languages.setLanguageConfiguration(GO_MODE.language, {
|
||||
indentationRules: {
|
||||
decreaseIndentPattern: /^\s*(\bcase\b.*:|\bdefault\b:|}[),]?|\)[,]?)$/,
|
||||
|
|
19
src/util.ts
19
src/util.ts
|
@ -409,3 +409,22 @@ export function resolvePath(inputPath: string, workspaceRoot?: string): string {
|
|||
return resolveHomeDir(inputPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the import path in a passed in string.
|
||||
* @param text The string to search for an import path
|
||||
*/
|
||||
export function getImportPath(text: string): string {
|
||||
// Catch cases like `import alias "importpath"` and `import "importpath"`
|
||||
let singleLineImportMatches = text.match(/^\s*import\s+([a-z,A-Z,_,\.]\w*\s+)?\"([^\"]+)\"/);
|
||||
if (singleLineImportMatches) {
|
||||
return singleLineImportMatches[2];
|
||||
}
|
||||
|
||||
// Catch cases like `alias "importpath"` and "importpath"
|
||||
let groupImportMatches = text.match(/^\s*([a-z,A-Z,_,\.]\w*\s+)?\"([^\"]+)\"/);
|
||||
if (groupImportMatches) {
|
||||
return groupImportMatches[2];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import { documentSymbols } from '../src/goOutline';
|
|||
import { listPackages } from '../src/goImport';
|
||||
import { generateTestCurrentFile, generateTestCurrentPackage, generateTestCurrentFunction } from '../src/goGenerateTests';
|
||||
import { getAllPackages } from '../src/goPackages';
|
||||
import { getImportPath } from '../src/util';
|
||||
|
||||
suite('Go Extension Tests', () => {
|
||||
let gopath = process.env['GOPATH'];
|
||||
|
@ -738,4 +739,19 @@ It returns the number of bytes written and any write error encountered.
|
|||
assert.ok(false, `error in OpenTextDocument ${err}`);
|
||||
}).then(() => done(), done);
|
||||
});
|
||||
|
||||
test('getImportPath()', () => {
|
||||
let testCases: [string, string][] = [
|
||||
['import "github.com/sirupsen/logrus"', 'github.com/sirupsen/logrus'],
|
||||
['import "net/http"', 'net/http'],
|
||||
['"github.com/sirupsen/logrus"', 'github.com/sirupsen/logrus'],
|
||||
['', ''],
|
||||
['func foo(bar int) (int, error) {', ''],
|
||||
['// This is a comment, complete with punctuation.', '']
|
||||
];
|
||||
|
||||
testCases.forEach(run => {
|
||||
assert.equal(run[1], getImportPath(run[0]));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче