src/goEnvironmentStatus.ts: integrated terminals respect go env setting

This CL is implements the fifth item in the following road map:

1. Create status bar item for switching Go binary (not implemented)
2. Create command palette menu for choosing the Go binary
3. Track the currently selected Go binary using workspace context
4. Show versions of Go that are not installed and allow them to be
selected and installed
5. Ensure new integrated terminals use the selected environment
6. Update workspace state to use settings.json instead
7. Detect if Go is not installed and prompt to install it
8. Detect if user has the latest version of Go installed and prompt them
to install it
9. Cache Go paths upon extension initialization for faster menu loading

This CL updates the environment in new integrated terminals using
settings.json. Any new integrated terminal the user opens after changing
Go versions will use the selected version.

Change-Id: I70ec6372bb2d40569b74a41edb32c40ea1c59bd3
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/240479
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/src/goEnvironmentStatus.ts b/src/goEnvironmentStatus.ts
index 51f8d40..4f24e85 100644
--- a/src/goEnvironmentStatus.ts
+++ b/src/goEnvironmentStatus.ts
@@ -15,6 +15,7 @@
 
 import { toolInstallationEnvironment } from './goEnv';
 import { getActiveGoRoot } from './goInstallTools';
+import { getCurrentGoRoot } from './goPath';
 import { outputChannel } from './goStatus';
 import { getBinPath, getGoConfig, getGoVersion } from './util';
 
@@ -35,6 +36,7 @@
 
 // statusbar item for switching the Go environment
 let goEnvStatusbarItem: vscode.StatusBarItem;
+let terminalCreationListener: vscode.Disposable;
 
 /**
  * Initialize the status bar item with current Go binary
@@ -47,6 +49,12 @@
 	const version = await getGoVersion();
 	const goOption = new GoEnvironmentOption(version.binaryPath, formatGoVersion(version.format()));
 
+	// ensure terminals use the correct Go version
+	if (!terminalCreationListener) {
+		updateIntegratedTerminal(vscode.window.activeTerminal);
+		terminalCreationListener = vscode.window.onDidOpenTerminal(updateIntegratedTerminal);
+	}
+
 	hideGoStatusBar();
 	goEnvStatusbarItem.text = goOption.label;
 	goEnvStatusbarItem.command = 'go.environment.choose';
@@ -60,6 +68,9 @@
 	if (!!goEnvStatusbarItem) {
 		goEnvStatusbarItem.dispose();
 	}
+	if (!!terminalCreationListener) {
+		terminalCreationListener.dispose();
+	}
 }
 
 /**
@@ -212,6 +223,21 @@
 }
 
 /**
+ * update the PATH variable in the given terminal to default to the currently selected Go
+ */
+export async function updateIntegratedTerminal(terminal: vscode.Terminal) {
+	const goroot = path.join(getCurrentGoRoot(), 'bin');
+
+	// TODO: add support for more terminal names
+	// this assumes all non-windows shells are bash-like.
+	if (terminal.name.toLowerCase() === 'powershell' || terminal.name.toLowerCase() === 'cmd') {
+		terminal.sendText(`set PATH=${goroot};%PATH%`, true);
+	} else {
+		terminal.sendText(`export PATH=${goroot}:$PATH`, true);
+	}
+}
+
+/**
  * retreive the current selected Go from the workspace state
  */
 export async function getSelectedGo(): Promise<GoEnvironmentOption> {