[release] all: merge master@d04d4cf

d04d4cf README.md: correct tools installation command name
03274ad src/goStatus: present error icon if gopls couldn't be found
465fe7e src/goLanguageServer.ts: prompt to update instead of silent update
607cebe src/welcome: add note about removing go.useLanguageServer setting

Change-Id: I43ff57a9698097b9e05e8e705082912cd41ac3d6
diff --git a/README.md b/README.md
index 4379056..1ed7a03 100644
--- a/README.md
+++ b/README.md
@@ -90,7 +90,7 @@
 not found, the extension will prompt you to install the missing tools and show
 the "⚠️ Analysis Tools Missing" warning in the bottom right corner. Please
 install them by responding to the warning notification, or by manually running
-the [`Go: Install/Update Go Tools` command].
+the [`Go: Install/Update Tools` command].
 
 ## Setting up your workspace
 
@@ -177,6 +177,6 @@
 [debugging]: #debugging
 [full feature breakdown]: https://github.com/golang/vscode-go/blob/master/docs/features.md
 [workspace documentation]: https://github.com/golang/tools/blob/master/gopls/doc/workspace.md
-[`Go: Install/Update Go Tools` command]: https://github.com/golang/vscode-go/blob/master/docs/commands.md#go-installupdate-tools
+[`Go: Install/Update Tools` command]: https://github.com/golang/vscode-go/blob/master/docs/commands.md#go-installupdate-tools
 [documentation about supported workspace layouts]: https://github.com/golang/tools/blob/master/gopls/doc/workspace.md
 [Workspace Folders]: https://code.visualstudio.com/docs/editor/multi-root-workspaces
diff --git a/src/goInstallTools.ts b/src/goInstallTools.ts
index 88cec70..128445c 100644
--- a/src/goInstallTools.ts
+++ b/src/goInstallTools.ts
@@ -303,7 +303,7 @@
 	}
 	const msg = `The "${tool.name}" command is not available.
 Run "go get -v ${getImportPath(tool, goVersion)}" to install.`;
-	const selected = await vscode.window.showInformationMessage(msg, ...installOptions);
+	const selected = await vscode.window.showErrorMessage(msg, ...installOptions);
 	switch (selected) {
 		case 'Install':
 			await installTools([tool], goVersion);
@@ -319,7 +319,11 @@
 	}
 }
 
-export async function promptForUpdatingTool(toolName: string, newVersion?: SemVer, crashed?: boolean) {
+export async function promptForUpdatingTool(
+	toolName: string,
+	newVersion?: SemVer,
+	crashed?: boolean,
+	message?: string) {
 	const tool = getTool(toolName);
 	const toolVersion = { ...tool, version: newVersion }; // ToolWithVersion
 
@@ -330,7 +334,9 @@
 
 	// Adjust the prompt if it occurred because the tool crashed.
 	let updateMsg: string;
-	if (crashed === true) {
+	if (message) {
+		updateMsg = message;
+	} else if (crashed === true) {
 		updateMsg = `${tool.name} has crashed, but you are using an outdated version. Please update to the latest version of ${tool.name}.`;
 	} else if (newVersion) {
 		updateMsg = `A new version of ${tool.name} (v${newVersion}) is available. Please update for an improved experience.`;
@@ -522,8 +528,8 @@
 
 async function suggestDownloadGo() {
 	const msg = `Failed to find the "go" binary in either GOROOT(${getCurrentGoRoot()}) or PATH(${envPath}).` +
-			`Check PATH, or Install Go and reload the window. ` +
-			`If PATH isn't what you expected, see https://github.com/golang/vscode-go/issues/971`;
+		`Check PATH, or Install Go and reload the window. ` +
+		`If PATH isn't what you expected, see https://github.com/golang/vscode-go/issues/971`;
 	if (suggestedDownloadGo) {
 		vscode.window.showErrorMessage(msg);
 		return;
diff --git a/src/goLanguageServer.ts b/src/goLanguageServer.ts
index 67dbd33..914d158 100644
--- a/src/goLanguageServer.ts
+++ b/src/goLanguageServer.ts
@@ -61,7 +61,6 @@
 	getBinPath,
 	getCheckForToolsUpdatesConfig,
 	getCurrentGoPath,
-	getGoVersion,
 	getWorkspaceFolderPath,
 	removeDuplicateDiagnostics
 } from './util';
@@ -138,11 +137,7 @@
 			// If the language server is turned on because it is enabled by default,
 			// make sure that the user is using a new enough version.
 			if (cfg.enabled && languageServerUsingDefault(goConfig)) {
-				const updated = await forceUpdateGopls(tool, cfg);
-				if (updated) {
-					// restartLanguageServer will be called when the new version of gopls was installed.
-					return;
-				}
+				suggestUpdateGopls(tool, cfg);
 			}
 		}
 	}
@@ -173,7 +168,8 @@
 			// We already created various notification - e.g. missing gopls, ...
 			// So, just leave a log message here instead of issuing one more notification.
 			outputChannel.appendLine(
-				`Failed to start the language server (${cfg.serverName}). Falling back to default language providers...`);
+				`Failed to start the language server (gopls). Falling back to default language providers...`);
+			outputChannel.show();
 		}
 		// If the server has been disabled, or failed to start,
 		// fall back to the default providers, while making sure not to
@@ -184,7 +180,7 @@
 
 		if (disposable) { disposable.dispose(); }
 		languageServerIsRunning = started;
-		updateLanguageServerIconGoStatusBar(started, cfg.serverName);
+		updateLanguageServerIconGoStatusBar(started, goConfig['useLanguageServer']);
 		languageServerStartInProgress = false;
 	});
 }
@@ -878,7 +874,7 @@
  * 				configuration.
  * @returns		true if the tool was updated
  */
-async function forceUpdateGopls(
+async function suggestUpdateGopls(
 	tool: Tool,
 	cfg: LanguageServerConfig,
 ): Promise<boolean> {
@@ -896,21 +892,11 @@
 
 	if (!latestVersion) {
 		// The user is using a new enough version
-		return false;
+		return;
 	}
 
-	const toolVersion = { ...tool, version: latestVersion }; // ToolWithVersion
-	const goVersion = await getGoVersion();
-	const failures = await installTools([toolVersion], goVersion);
-
-	// We successfully updated to the latest version.
-	if (failures.length === 0) {
-		return true;
-	}
-
-	// Failed to install the new version of gopls, warn the user.
-	vscode.window.showWarningMessage(`'gopls' is now enabled by default and you are using an old version. Please [update 'gopls'](https://github.com/golang/tools/blob/master/gopls/doc/user.md#installation) and restart the language server for the best experience.`);
-	return false;
+	const updateMsg = `'gopls' is now enabled by default and you are using an old version. Please [update 'gopls'](https://github.com/golang/tools/blob/master/gopls/README.md#installation) for the best experience.`;
+	promptForUpdatingTool(tool.name, latestVersion, false, updateMsg);
 }
 
 // Copied from src/cmd/go/internal/modfetch.go.
diff --git a/src/goStatus.ts b/src/goStatus.ts
index 3f31d04..d3306ef 100644
--- a/src/goStatus.ts
+++ b/src/goStatus.ts
@@ -13,6 +13,7 @@
 import { buildLanguageServerConfig, getLocalGoplsVersion, languageServerIsRunning, serverOutputChannel } from './goLanguageServer';
 import { isGoFile } from './goMode';
 import { getModFolderPath, isModSupported } from './goModules';
+import { allToolsInformation } from './goTools';
 import { getGoVersion } from './util';
 
 export let outputChannel = vscode.window.createOutputChannel('Go');
@@ -24,6 +25,7 @@
 
 let modulePath: string;
 export const languageServerIcon = '$(zap)';
+export const languageServerErrorIcon = '$(warning)';
 
 export function updateGoStatusBar(editor: vscode.TextEditor) {
 	// Only update the module path if we are in a Go file.
@@ -47,11 +49,17 @@
 	];
 
 	// Get the gopls configuration
-	const cfg = buildLanguageServerConfig(getGoConfig());
+	const goConfig = getGoConfig();
+	const cfg = buildLanguageServerConfig(goConfig);
 	if (languageServerIsRunning && cfg.serverName === 'gopls') {
 		const goplsVersion = await getLocalGoplsVersion(cfg);
 		options.push({label: `${languageServerIcon}Open 'gopls' trace`, description: `${goplsVersion}`});
 	}
+	if (!languageServerIsRunning && !cfg.serverName && goConfig['useLanguageServer']) {
+		options.push({
+			label: `Install Go Language Server`,
+			description: `${languageServerErrorIcon}'gopls' is required but missing`});
+	}
 
 	// If modules is enabled, add link to mod file
 	if (!!modulePath) {
@@ -72,6 +80,9 @@
 						serverOutputChannel.show();
 					}
 					break;
+				case `Install Go Language Server`:
+					vscode.commands.executeCommand('go.tools.install', [allToolsInformation['gopls']]);
+					break;
 				case `Open 'go.mod'`:
 					const openPath = vscode.Uri.file(item.description);
 					vscode.workspace.openTextDocument(openPath).then((doc) => {
@@ -101,27 +112,37 @@
 	// Add an icon to indicate that the 'gopls' server is running.
 	// Assume if it is configured it is already running, since the
 	// icon will be updated on an attempt to start.
-	const cfg = buildLanguageServerConfig(getGoConfig());
-	updateLanguageServerIconGoStatusBar(languageServerIsRunning, cfg.serverName);
+	const goConfig = getGoConfig();
+	const cfg = buildLanguageServerConfig(goConfig);
+	updateLanguageServerIconGoStatusBar(languageServerIsRunning, goConfig['useLanguageServer']);
 
 	showGoStatusBar();
 }
 
-export async function updateLanguageServerIconGoStatusBar(started: boolean, server: string) {
+export function updateLanguageServerIconGoStatusBar(started: boolean, enabled: boolean) {
 	if (!goEnvStatusbarItem) {
 		return;
 	}
 
-	const text = goEnvStatusbarItem.text;
-	if (started && server === 'gopls') {
-		if (!text.endsWith(languageServerIcon)) {
-			goEnvStatusbarItem.text = text + languageServerIcon;
-		}
-	} else {
-		if (text.endsWith(languageServerIcon)) {
-			goEnvStatusbarItem.text = text.substring(0, text.length - languageServerIcon.length);
-		}
+	// Split the existing goEnvStatusbarItem.text into the version string part and
+	// the gopls icon part.
+	let text = goEnvStatusbarItem.text;
+	let icon = '';
+	if (text.endsWith(languageServerIcon)) {
+		icon = languageServerIcon;
+		text = text.substring(0, text.length - languageServerIcon.length);
+	} else if (text.endsWith(languageServerErrorIcon)) {
+		icon = languageServerErrorIcon;
+		text = text.substring(0, text.length - languageServerErrorIcon.length);
 	}
+
+	if (started && enabled) {
+		icon = languageServerIcon;
+	} else if (!started && enabled) {
+		icon = languageServerErrorIcon;
+	}
+
+	goEnvStatusbarItem.text = text + icon;
 }
 
 /**
diff --git a/src/welcome.ts b/src/welcome.ts
index d41ac26..5bd08f9 100644
--- a/src/welcome.ts
+++ b/src/welcome.ts
@@ -7,6 +7,7 @@
 // https://github.com/microsoft/vscode-extension-samples/tree/master/webview-sample
 
 import vscode = require('vscode');
+import { getGoConfig } from './config';
 import { extensionId } from './const';
 
 export class WelcomePanel {
@@ -123,6 +124,14 @@
 		// Use a nonce to only allow specific scripts to be run
 		const nonce = getNonce();
 
+		// Add an extra note if the user has already disabled gopls, asking
+		// them to enable it.
+		let alreadyDisabledGopls = '';
+		if (getGoConfig()?.get('useLanguageServer') === false) {
+			alreadyDisabledGopls = `If you previously disabled gopls through the "go.useLanguageServer"
+setting, we recommend removing that setting now.`;
+		}
+
 		return `<!DOCTYPE html>
 			<html lang="en">
 			<head>
@@ -161,7 +170,7 @@
 					Heads up! Gopls, the official Go language server, is now enabled in VS Code by default.
 					Gopls replaces several legacy tools to provide IDE features while editing Go code.
 					See <a href="https://github.com/golang/vscode-go/issues/1037">issue 1037</a> for more
-					information.
+					information. ${alreadyDisabledGopls}
 				</p>
 			</div>