src/goMain.ts: simplify command registration
Consolidated the boilerplate to register commands into
a helper function to improve readability.
Change-Id: I083ed708e5f89f3919408cba4ef2023ed7dd6fb2
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/404375
Run-TryBot: Jamal Carvalho <jamal@golang.org>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
diff --git a/src/commands/index.ts b/src/commands/index.ts
index edc0cdd..8a94354 100644
--- a/src/commands/index.ts
+++ b/src/commands/index.ts
@@ -3,4 +3,16 @@
* Licensed under the MIT License. See LICENSE in the project root for license information.
*--------------------------------------------------------*/
+import * as vscode from 'vscode';
+
+import { GoExtensionContext } from '../context';
+
export { startLanguageServer } from './startLanguageServer';
+
+type CommandCallback<T extends unknown[]> = (...args: T) => Promise<unknown> | unknown;
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export type CommandFactory<T extends unknown[] = any[]> = (
+ ctx: vscode.ExtensionContext,
+ goCtx: GoExtensionContext
+) => CommandCallback<T>;
diff --git a/src/goMain.ts b/src/goMain.ts
index 38909e1..541979a 100644
--- a/src/goMain.ts
+++ b/src/goMain.ts
@@ -153,11 +153,6 @@
if (!extensionInfo.isInCloudIDE) {
showGoWelcomePage(ctx);
}
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.welcome', () => {
- WelcomePanel.createOrShow(ctx.extensionUri);
- })
- );
const configGOROOT = getGoConfig()['goroot'];
if (configGOROOT) {
@@ -208,25 +203,6 @@
await commands.startLanguageServer(ctx, goCtx)(RestartReason.ACTIVATION);
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.languageserver.restart', async (reason = RestartReason.MANUAL) => {
- if (reason === RestartReason.MANUAL) {
- await suggestGoplsIssueReport(
- goCtx,
- "Looks like you're about to manually restart the language server.",
- errorKind.manualRestart
- );
- }
- commands.startLanguageServer(ctx, goCtx)(reason);
- })
- );
-
- // Subscribe to notifications for changes to the configuration
- // of the language server, even if it's not currently in use.
- ctx.subscriptions.push(
- vscode.workspace.onDidChangeConfiguration((e) => watchLanguageServerConfiguration(goCtx, e))
- );
-
const activeDoc = vscode.window.activeTextEditor?.document;
if (!goCtx.languageServerIsRunning && activeDoc?.languageId === 'go' && isGoPathSet()) {
// Check mod status so that cache is updated and then run build/lint/vet
@@ -237,11 +213,19 @@
initCoverageDecorators(ctx);
+ const registerCommand = createRegisterCommand(ctx, goCtx);
+
+ registerCommand('go.languageserver.restart', commands.startLanguageServer);
+
+ // Subscribe to notifications for changes to the configuration
+ // of the language server, even if it's not currently in use.
ctx.subscriptions.push(
- vscode.commands.registerCommand('go.environment.status', async () => {
- expandGoStatusBar(goCtx);
- })
+ vscode.workspace.onDidChangeConfiguration((e) => watchLanguageServerConfiguration(goCtx, e))
);
+
+ registerCommand('go.welcome', (ctx) => () => WelcomePanel.createOrShow(ctx.extensionUri));
+ registerCommand('go.environment.status', (_ctx, goCtx) => () => expandGoStatusBar(goCtx));
+
const testCodeLensProvider = new GoRunTestCodeLensProvider();
const referencesCodeLensProvider = new GoReferencesCodeLensProvider();
@@ -252,22 +236,8 @@
ctx.subscriptions.push(
vscode.debug.registerDebugConfigurationProvider('go', new GoDebugConfigurationProvider('go'))
);
- ctx.subscriptions.push(
- vscode.commands.registerCommand(
- 'go.debug.pickProcess',
- async (): Promise<string> => {
- return await pickProcess();
- }
- )
- );
- ctx.subscriptions.push(
- vscode.commands.registerCommand(
- 'go.debug.pickGoProcess',
- async (): Promise<string> => {
- return await pickGoProcess();
- }
- )
- );
+ registerCommand('go.debug.pickProcess', () => pickProcess);
+ registerCommand('go.debug.pickGoProcess', () => pickGoProcess);
const debugOutputChannel = vscode.window.createOutputChannel('Go Debug');
ctx.subscriptions.push(debugOutputChannel);
@@ -297,67 +267,16 @@
addOnChangeActiveTextEditorListeners(ctx);
addOnSaveTextDocumentListeners(ctx);
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.gopath', () => {
- getCurrentGoPathCommand();
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.locate.tools', async () => {
- getConfiguredGoToolsCommand();
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.add.tags', (args) => {
- addTags(args);
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.remove.tags', (args) => {
- removeTags(args);
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.fill.struct', () => {
- if (vscode.window.activeTextEditor) {
- runFillStruct(vscode.window.activeTextEditor);
- }
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.impl.cursor', () => {
- implCursor();
- })
- );
- 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) => {
- const goConfig = getGoConfig();
- testAtCursor(goConfig, 'test', args);
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.test.cursorOrPrevious', (args) => {
- const goConfig = getGoConfig();
- testAtCursorOrPrevious(goConfig, 'test', args);
- })
- );
+ registerCommand('go.gopath', () => getCurrentGoPathCommand);
+ registerCommand('go.locate.tools', () => getConfiguredGoToolsCommand);
+ registerCommand('go.add.tags', () => addTags);
+ registerCommand('go.remove.tags', () => removeTags);
+ registerCommand('go.fill.struct', () => () => runFillStruct(vscode.window.activeTextEditor));
+ registerCommand('go.impl.cursor', () => implCursor);
+ registerCommand('go.godoctor.extract', () => extractFunction);
+ registerCommand('go.godoctor.var', () => extractVariable);
+ registerCommand('go.test.cursor', () => (args) => testAtCursor(getGoConfig(), 'test', args));
+ registerCommand('go.test.cursorOrPrevious', () => (args) => testAtCursorOrPrevious(getGoConfig(), 'test', args));
if (isVscodeTestingAPIAvailable && cfg.get<boolean>('testExplorer.enable')) {
GoTestExplorer.setup(ctx);
@@ -366,124 +285,32 @@
GoExplorerProvider.setup(ctx);
VulncheckProvider.setup(ctx, goCtx);
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.subtest.cursor', (args) => {
- const goConfig = getGoConfig();
- subTestAtCursor(goConfig, args);
- })
- );
+ registerCommand('go.subtest.cursor', () => (args) => subTestAtCursor(getGoConfig(), args));
+ registerCommand('go.debug.cursor', () => (args) => testAtCursor(getGoConfig(), 'debug', args));
+ registerCommand('go.benchmark.cursor', () => (args) => testAtCursor(getGoConfig(), 'benchmark', args));
+ registerCommand('go.test.package', () => (args) => testCurrentPackage(getGoConfig(), false, args));
+ registerCommand('go.benchmark.package', () => (args) => testCurrentPackage(getGoConfig(), true, args));
+ registerCommand('go.test.file', () => (args) => testCurrentFile(getGoConfig(), false, args));
+ registerCommand('go.benchmark.file', () => (args) => testCurrentFile(getGoConfig(), true, args));
+ registerCommand('go.test.workspace', () => (args) => testWorkspace(getGoConfig(), args));
+ registerCommand('go.test.previous', () => testPrevious);
+ registerCommand('go.debug.previous', () => debugPrevious);
+ registerCommand('go.test.coverage', () => toggleCoverageCurrentPackage);
+ registerCommand('go.test.showOutput', () => showTestOutput);
+ registerCommand('go.test.cancel', () => cancelRunningTests);
+ registerCommand('go.import.add', () => (arg) => addImport(goCtx, arg));
+ registerCommand('go.add.package.workspace', () => addImportToWorkspace);
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.debug.cursor', (args) => {
- const goConfig = getGoConfig();
- testAtCursor(goConfig, 'debug', args);
- })
- );
+ registerCommand('go.tools.install', () => async (args) => {
+ if (Array.isArray(args) && args.length) {
+ const goVersion = await getGoVersion();
+ await installTools(args, goVersion);
+ return;
+ }
+ installAllTools();
+ });
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.benchmark.cursor', (args) => {
- const goConfig = getGoConfig();
- testAtCursor(goConfig, 'benchmark', args);
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.test.package', (args) => {
- const goConfig = getGoConfig();
- const isBenchmark = false;
- testCurrentPackage(goConfig, isBenchmark, args);
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.benchmark.package', (args) => {
- const goConfig = getGoConfig();
- const isBenchmark = true;
- testCurrentPackage(goConfig, isBenchmark, args);
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.test.file', (args) => {
- const goConfig = getGoConfig();
- const isBenchmark = false;
- testCurrentFile(goConfig, isBenchmark, args);
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.benchmark.file', (args) => {
- const goConfig = getGoConfig();
- const isBenchmark = true;
- testCurrentFile(goConfig, isBenchmark, args);
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.test.workspace', (args) => {
- const goConfig = getGoConfig();
- testWorkspace(goConfig, args);
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.test.previous', () => {
- testPrevious();
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.debug.previous', () => {
- debugPrevious();
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.test.coverage', () => {
- toggleCoverageCurrentPackage();
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.test.showOutput', () => {
- showTestOutput();
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.test.cancel', () => {
- cancelRunningTests();
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.import.add', (arg) => {
- return addImport(goCtx, arg);
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.add.package.workspace', () => {
- addImportToWorkspace();
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.tools.install', async (args) => {
- if (Array.isArray(args) && args.length) {
- const goVersion = await getGoVersion();
- await installTools(args, goVersion);
- return;
- }
- installAllTools();
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.browse.packages', () => {
- browsePackages();
- })
- );
+ registerCommand('go.browse.packages', () => browsePackages);
ctx.subscriptions.push(
vscode.workspace.onDidChangeConfiguration(async (e: vscode.ConfigurationChangeEvent) => {
@@ -565,174 +392,117 @@
})
);
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.test.generate.package', () => {
- goGenerateTests.generateTestCurrentPackage();
- })
- );
+ registerCommand('go.test.generate.package', () => goGenerateTests.generateTestCurrentPackage);
+ registerCommand('go.test.generate.file', () => goGenerateTests.generateTestCurrentFile);
+ registerCommand('go.test.generate.function', () => goGenerateTests.generateTestCurrentFunction);
+ registerCommand('go.toggle.test.file', () => goGenerateTests.toggleTestFile);
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.test.generate.file', () => {
- goGenerateTests.generateTestCurrentFile();
- })
- );
+ registerCommand('go.debug.startSession', () => (config) => {
+ let workspaceFolder;
+ if (vscode.window.activeTextEditor) {
+ workspaceFolder = vscode.workspace.getWorkspaceFolder(vscode.window.activeTextEditor.document.uri);
+ }
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.test.generate.function', () => {
- goGenerateTests.generateTestCurrentFunction();
- })
- );
+ return vscode.debug.startDebugging(workspaceFolder, config);
+ });
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.toggle.test.file', () => {
- goGenerateTests.toggleTestFile();
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.debug.startSession', (config) => {
- let workspaceFolder;
- if (vscode.window.activeTextEditor) {
- workspaceFolder = vscode.workspace.getWorkspaceFolder(vscode.window.activeTextEditor.document.uri);
+ registerCommand('go.show.commands', () => () => {
+ const extCommands = getExtensionCommands();
+ extCommands.push({
+ command: 'editor.action.goToDeclaration',
+ title: 'Go to Definition'
+ });
+ extCommands.push({
+ command: 'editor.action.goToImplementation',
+ title: 'Go to Implementation'
+ });
+ extCommands.push({
+ command: 'workbench.action.gotoSymbol',
+ title: 'Go to Symbol in File...'
+ });
+ extCommands.push({
+ command: 'workbench.action.showAllSymbols',
+ title: 'Go to Symbol in Workspace...'
+ });
+ vscode.window.showQuickPick(extCommands.map((x) => x.title)).then((cmd) => {
+ const selectedCmd = extCommands.find((x) => x.title === cmd);
+ if (selectedCmd) {
+ vscode.commands.executeCommand(selectedCmd.command);
}
+ });
+ });
- return vscode.debug.startDebugging(workspaceFolder, config);
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.show.commands', () => {
- const extCommands = getExtensionCommands();
- extCommands.push({
- command: 'editor.action.goToDeclaration',
- title: 'Go to Definition'
- });
- extCommands.push({
- command: 'editor.action.goToImplementation',
- title: 'Go to Implementation'
- });
- extCommands.push({
- command: 'workbench.action.gotoSymbol',
- title: 'Go to Symbol in File...'
- });
- extCommands.push({
- command: 'workbench.action.showAllSymbols',
- title: 'Go to Symbol in Workspace...'
- });
- vscode.window.showQuickPick(extCommands.map((x) => x.title)).then((cmd) => {
- const selectedCmd = extCommands.find((x) => x.title === cmd);
- if (selectedCmd) {
- vscode.commands.executeCommand(selectedCmd.command);
- }
- });
- })
- );
-
- ctx.subscriptions.push(vscode.commands.registerCommand('go.get.package', goGetPackage));
-
- ctx.subscriptions.push(vscode.commands.registerCommand('go.playground', playgroundCommand));
-
- ctx.subscriptions.push(vscode.commands.registerCommand('go.lint.package', () => lintCode('package')));
-
- ctx.subscriptions.push(vscode.commands.registerCommand('go.lint.workspace', () => lintCode('workspace')));
-
- ctx.subscriptions.push(vscode.commands.registerCommand('go.lint.file', () => lintCode('file')));
-
- ctx.subscriptions.push(vscode.commands.registerCommand('go.vet.package', vetCode));
-
- ctx.subscriptions.push(vscode.commands.registerCommand('go.vet.workspace', () => vetCode(true)));
-
- ctx.subscriptions.push(vscode.commands.registerCommand('go.build.package', buildCode));
-
- ctx.subscriptions.push(vscode.commands.registerCommand('go.build.workspace', () => buildCode(true)));
-
- ctx.subscriptions.push(vscode.commands.registerCommand('go.install.package', installCurrentPackage));
-
- ctx.subscriptions.push(vscode.commands.registerCommand('go.run.modinit', goModInit));
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.extractServerChannel', () => {
- showServerOutputChannel(goCtx);
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.workspace.resetState', () => {
- resetWorkspaceState();
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.global.resetState', () => {
- resetGlobalState();
- })
- );
-
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.toggle.gc_details', () => {
- if (!goCtx.languageServerIsRunning) {
+ registerCommand('go.get.package', () => goGetPackage);
+ registerCommand('go.playground', () => playgroundCommand);
+ registerCommand('go.lint.package', () => () => lintCode('package'));
+ registerCommand('go.lint.workspace', () => () => lintCode('workspace'));
+ registerCommand('go.lint.file', () => () => lintCode('file'));
+ registerCommand('go.vet.package', () => vetCode);
+ registerCommand('go.vet.workspace', () => () => vetCode(true));
+ registerCommand('go.build.package', () => buildCode);
+ registerCommand('go.build.workspace', () => () => buildCode(true));
+ registerCommand('go.install.package', () => installCurrentPackage);
+ registerCommand('go.run.modinit', () => goModInit);
+ registerCommand('go.extractServerChannel', (_ctx, goCtx) => () => showServerOutputChannel(goCtx));
+ registerCommand('go.workspace.resetState', () => resetWorkspaceState);
+ registerCommand('go.global.resetState', () => resetGlobalState);
+ registerCommand('go.toggle.gc_details', () => () => {
+ if (!goCtx.languageServerIsRunning) {
+ vscode.window.showErrorMessage(
+ '"Go: Toggle gc details" command is available only when the language server is running'
+ );
+ return;
+ }
+ const doc = vscode.window.activeTextEditor?.document.uri.toString();
+ if (!doc || !doc.endsWith('.go')) {
+ vscode.window.showErrorMessage('"Go: Toggle gc details" command cannot run when no Go file is open.');
+ return;
+ }
+ vscode.commands.executeCommand('gc_details', doc).then(undefined, (reason0) => {
+ vscode.commands.executeCommand('gopls.gc_details', doc).then(undefined, (reason1) => {
vscode.window.showErrorMessage(
- '"Go: Toggle gc details" command is available only when the language server is running'
+ `"Go: Toggle gc details" command failed: gc_details:${reason0} gopls_gc_details:${reason1}`
);
- return;
- }
- const doc = vscode.window.activeTextEditor?.document.uri.toString();
- if (!doc || !doc.endsWith('.go')) {
- vscode.window.showErrorMessage('"Go: Toggle gc details" command cannot run when no Go file is open.');
- return;
- }
- vscode.commands.executeCommand('gc_details', doc).then(undefined, (reason0) => {
- vscode.commands.executeCommand('gopls.gc_details', doc).then(undefined, (reason1) => {
- vscode.window.showErrorMessage(
- `"Go: Toggle gc details" command failed: gc_details:${reason0} gopls_gc_details:${reason1}`
- );
- });
});
- })
- );
+ });
+ });
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.apply.coverprofile', () => {
- if (!vscode.window.activeTextEditor || !vscode.window.activeTextEditor.document.fileName.endsWith('.go')) {
- vscode.window.showErrorMessage('Cannot apply coverage profile when no Go file is open.');
- return;
- }
- const lastCoverProfilePathKey = 'lastCoverProfilePathKey';
- const lastCoverProfilePath = getFromWorkspaceState(lastCoverProfilePathKey, '');
- vscode.window
- .showInputBox({
- prompt: 'Enter the path to the coverage profile for current package',
- value: lastCoverProfilePath
- })
- .then((coverProfilePath) => {
- if (!coverProfilePath) {
- return;
- }
- if (!fileExists(coverProfilePath)) {
- vscode.window.showErrorMessage(`Cannot find the file ${coverProfilePath}`);
- return;
- }
- if (coverProfilePath !== lastCoverProfilePath) {
- updateWorkspaceState(lastCoverProfilePathKey, coverProfilePath);
- }
- applyCodeCoverageToAllEditors(
- coverProfilePath,
- getWorkspaceFolderPath(vscode.window.activeTextEditor?.document.uri)
- );
- });
- })
- );
+ registerCommand('go.apply.coverprofile', () => () => {
+ if (!vscode.window.activeTextEditor || !vscode.window.activeTextEditor.document.fileName.endsWith('.go')) {
+ vscode.window.showErrorMessage('Cannot apply coverage profile when no Go file is open.');
+ return;
+ }
+ const lastCoverProfilePathKey = 'lastCoverProfilePathKey';
+ const lastCoverProfilePath = getFromWorkspaceState(lastCoverProfilePathKey, '');
+ vscode.window
+ .showInputBox({
+ prompt: 'Enter the path to the coverage profile for current package',
+ value: lastCoverProfilePath
+ })
+ .then((coverProfilePath) => {
+ if (!coverProfilePath) {
+ return;
+ }
+ if (!fileExists(coverProfilePath)) {
+ vscode.window.showErrorMessage(`Cannot find the file ${coverProfilePath}`);
+ return;
+ }
+ if (coverProfilePath !== lastCoverProfilePath) {
+ updateWorkspaceState(lastCoverProfilePathKey, coverProfilePath);
+ }
+ applyCodeCoverageToAllEditors(
+ coverProfilePath,
+ getWorkspaceFolderPath(vscode.window.activeTextEditor?.document.uri)
+ );
+ });
+ });
// Go Enviornment switching commands
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.environment.choose', () => {
- chooseGoEnvironment();
- })
- );
+ registerCommand('go.environment.choose', () => chooseGoEnvironment);
// Survey related commands
- ctx.subscriptions.push(vscode.commands.registerCommand('go.survey.showConfig', () => showSurveyConfig(goCtx)));
- ctx.subscriptions.push(vscode.commands.registerCommand('go.survey.resetConfig', () => resetSurveyConfigs()));
+ registerCommand('go.survey.showConfig', (_ctx, goCtx) => () => showSurveyConfig(goCtx));
+ registerCommand('go.survey.resetConfig', () => resetSurveyConfigs);
vscode.languages.setLanguageConfiguration(GO_MODE.language, {
wordPattern: /(-?\d*\.\d\w*)|([^`~!@#%^&*()\-=+[{\]}\\|;:'",.<>/?\s]+)/g
@@ -1090,3 +860,9 @@
delete process.env.GOROOT;
}
}
+
+function createRegisterCommand(ctx: vscode.ExtensionContext, goCtx: GoExtensionContext) {
+ return function registerCommand(name: string, fn: commands.CommandFactory) {
+ ctx.subscriptions.push(vscode.commands.registerCommand(name, fn(ctx, goCtx)));
+ };
+}