goLanguageServer: add command to toggle gc_details

A new vscode-go command go.toggle.gc_details gives a way to
display gc optimization decisions for the file in the active editor.
The user see 'Go: Toggle gc_details' in the command menu,

This supplements, and does the same thing, as the gc_details code lens.

Change-Id: I25284d10901fd47f0029f627066ede7e828b45da
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/256658
Run-TryBot: Peter Weinberger <pjw@google.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Trust: Peter Weinberger <pjw@google.com>
diff --git a/docs/commands.md b/docs/commands.md
index 11f0984..03a9919 100644
--- a/docs/commands.md
+++ b/docs/commands.md
@@ -91,6 +91,10 @@
 
 Generates method stub for implementing the provided interface and inserts at the cursor.
 
+### `Go: Toggle gc details`
+
+Toggle the display of compiler optimization choices
+
 ### `Go: Add Import`
 
 Add an import declaration
diff --git a/package.json b/package.json
index 3bc3086..81f380f 100644
--- a/package.json
+++ b/package.json
@@ -240,6 +240,11 @@
         "description": "Generates method stub for implementing the provided interface and inserts at the cursor."
       },
       {
+        "command": "go.toggle.gc_details",
+        "title": "Go: Toggle gc details",
+        "description": "Toggle the display of compiler optimization choices"
+      },
+      {
         "command": "go.import.add",
         "title": "Go: Add Import",
         "description": "Add an import declaration"
@@ -2050,4 +2055,4 @@
       ]
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/goLanguageServer.ts b/src/goLanguageServer.ts
index 33293a2..cdf23ad 100644
--- a/src/goLanguageServer.ts
+++ b/src/goLanguageServer.ts
@@ -18,6 +18,9 @@
 	CloseAction,
 	CompletionItemKind,
 	ErrorAction,
+	ExecuteCommandParams,
+	ExecuteCommandRequest,
+	ExecuteCommandSignature,
 	HandleDiagnosticsSignature,
 	InitializeError,
 	LanguageClient,
@@ -25,7 +28,7 @@
 	ProvideCodeLensesSignature,
 	ProvideCompletionItemsSignature,
 	ProvideDocumentLinksSignature,
-	RevealOutputChannelOn,
+	RevealOutputChannelOn
 } from 'vscode-languageclient';
 import WebRequest = require('web-request');
 import { extensionId } from './const';
@@ -400,6 +403,22 @@
 	return c;
 }
 
+export function sendToggleCommand(cmd: string, file: vscode.Uri) {
+	if (languageClient === undefined || file === undefined) {
+		return;
+	}
+	const params: ExecuteCommandParams = {
+		command: cmd,
+		arguments: [file.toString()],
+	};
+	languageClient.sendRequest(ExecuteCommandRequest.type, params).then(
+		undefined,
+		(error: any) => {
+			return languageClient.logFailedRequest(ExecuteCommandRequest.type, error);
+		}
+	);
+}
+
 // createTestCodeLens adds the go.test.cursor and go.debug.cursor code lens
 function createTestCodeLens(lens: vscode.CodeLens): vscode.CodeLens[] {
 	// CodeLens argument signature in gopls is [fileName: string, testFunctions: string[], benchFunctions: string[]],
diff --git a/src/goMain.ts b/src/goMain.ts
index 7b7d714..9889ed3 100644
--- a/src/goMain.ts
+++ b/src/goMain.ts
@@ -29,7 +29,7 @@
 	installAllTools, installTools, offerToInstallTools, promptForMissingTool,
 	updateGoVarsFromConfig
 } from './goInstallTools';
-import { startLanguageServerWithFallback, watchLanguageServerConfiguration } from './goLanguageServer';
+import { sendToggleCommand, startLanguageServerWithFallback, watchLanguageServerConfiguration } from './goLanguageServer';
 import { lintCode } from './goLint';
 import { logVerbose, setLogConfig } from './goLogging';
 import { GO_MODE } from './goMode';
@@ -443,6 +443,10 @@
 
 	ctx.subscriptions.push(vscode.commands.registerCommand('go.install.package', installCurrentPackage));
 
+	ctx.subscriptions.push(vscode.commands.registerCommand('go.toggle.gc_details', () => {
+		sendToggleCommand('gc_details', vscode.window.activeTextEditor?.document.uri);
+	}));
+
 	ctx.subscriptions.push(
 		vscode.commands.registerCommand('go.apply.coverprofile', () => {
 			if (!vscode.window.activeTextEditor || !vscode.window.activeTextEditor.document.fileName.endsWith('.go')) {