goLanguageServer: send the gopls config as initialization options

Workspace symbols relies on the session's options, not the view's.
These options are set via initialization options, rather than
workspace/configuration. Send any user configs on start-up.

Change-Id: Ic8e6085764b777ee9e3e67c8a1f01fe53c447cbf
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/259138
Trust: Rebecca Stambler <rstambler@golang.org>
Trust: Hyang-Ah Hana Kim <hyangah@gmail.com>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/src/goLanguageServer.ts b/src/goLanguageServer.ts
index fb64411..b577ae4 100644
--- a/src/goLanguageServer.ts
+++ b/src/goLanguageServer.ts
@@ -52,7 +52,7 @@
 import { getTool, Tool } from './goTools';
 import { GoTypeDefinitionProvider } from './goTypeDefinition';
 import { getFromGlobalState, updateGlobalState } from './stateUtils';
-import { getBinPath, getCurrentGoPath, getGoConfig, getWorkspaceFolderPath } from './util';
+import { getBinPath, getCurrentGoPath, getGoConfig, getGoplsConfig, getWorkspaceFolderPath } from './util';
 import { getToolFromToolPath } from './utils/pathUtils';
 
 interface LanguageServerConfig {
@@ -210,6 +210,7 @@
 			serverTraceChannel = vscode.window.createOutputChannel(config.serverName);
 		}
 	}
+	const goplsConfig = getGoplsConfig();
 	const c = new LanguageClient(
 		'go',  // id
 		config.serverName,  // name
@@ -219,7 +220,7 @@
 			options: { env: config.env },
 		},
 		{
-			initializationOptions: {},
+			initializationOptions: goplsConfig,
 			documentSelector: ['go', 'go.mod', 'go.sum'],
 			uriConverters: {
 				// Apply file:/// scheme to all file paths.
diff --git a/src/util.ts b/src/util.ts
index ee361b4..1c49bf8 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -158,6 +158,15 @@
 
 // getGoConfig is declared as an exported const rather than a function, so it can be stubbbed in testing.
 export const getGoConfig = (uri?: vscode.Uri) => {
+	return getConfig('go');
+};
+
+// getGoplsConfig returns the user's gopls configuration.
+export function getGoplsConfig() {
+	return getConfig('gopls');
+}
+
+function getConfig(section: string, uri?: vscode.Uri) {
 	if (!uri) {
 		if (vscode.window.activeTextEditor) {
 			uri = vscode.window.activeTextEditor.document.uri;
@@ -165,8 +174,8 @@
 			uri = null;
 		}
 	}
-	return vscode.workspace.getConfiguration('go', uri);
-};
+	return vscode.workspace.getConfiguration(section, uri);
+}
 
 export function byteOffsetAt(document: vscode.TextDocument, position: vscode.Position): number {
 	const offset = document.offsetAt(position);
@@ -344,7 +353,7 @@
 		const docUri = vscode.window.activeTextEditor?.document.uri;
 		const cwd = getWorkspaceFolderPath(docUri && docUri.fsPath.endsWith('.go') ? docUri : undefined);
 		const execFile = util.promisify(cp.execFile);
-		const { stdout, stderr } = await execFile(goRuntimePath, ['version'], {env, cwd});
+		const { stdout, stderr } = await execFile(goRuntimePath, ['version'], { env, cwd });
 		if (stderr) {
 			warn(`failed to run "${goRuntimePath} version": stdout: ${stdout}, stderr: ${stderr}`);
 			return;
@@ -352,7 +361,7 @@
 		cachedGoBinPath = goRuntimePath;
 		cachedGoVersion = new GoVersion(goRuntimePath, stdout);
 		if (!cachedGoVersion.isValid()) {
-			warn (`unable to determine version from the output of "${goRuntimePath} version": "${stdout}"`);
+			warn(`unable to determine version from the output of "${goRuntimePath} version": "${stdout}"`);
 		}
 	} catch (err) {
 		warn(`failed to run "${goRuntimePath} version": ${err}`);
@@ -368,7 +377,7 @@
 export async function getGoEnv(cwd?: string): Promise<string> {
 	const goRuntime = getBinPath('go');
 	const execFile = util.promisify(cp.execFile);
-	const opts = {cwd, env: toolExecutionEnvironment()};
+	const opts = { cwd, env: toolExecutionEnvironment() };
 	const { stdout, stderr } = await execFile(goRuntime, ['env'], opts);
 	if (stderr) {
 		throw new Error(`failed to run 'go env': ${stderr}`);
@@ -485,7 +494,7 @@
 
 // getBinPathWithExplanation returns the path to the tool, and the explanation on why
 // the path was chosen. See getBinPathWithPreferredGopathGorootWithExplanation for details.
-export function getBinPathWithExplanation(tool: string, useCache = true): {binPath: string, why?: string} {
+export function getBinPathWithExplanation(tool: string, useCache = true): { binPath: string, why?: string } {
 	const cfg = getGoConfig();
 	const alternateTools: { [key: string]: string } = cfg.get('alternateTools');
 	const alternateToolPath: string = alternateTools[tool];
@@ -904,7 +913,7 @@
 	}
 }
 
-export function getWorkspaceFolderPath(fileUri?: vscode.Uri): string|undefined {
+export function getWorkspaceFolderPath(fileUri?: vscode.Uri): string | undefined {
 	if (fileUri) {
 		const workspace = vscode.workspace.getWorkspaceFolder(fileUri);
 		if (workspace) {