goLanguageServer: prompt user to fill out survey when they disable gopls
Change-Id: Iaa28bbb4fa590028d7582543f35cb798717f2713
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/291010
Trust: Rebecca Stambler <rstambler@golang.org>
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 50d24fa..a4157e6 100644
--- a/src/goLanguageServer.ts
+++ b/src/goLanguageServer.ts
@@ -199,16 +199,8 @@
if (cfg.serverName !== '') {
return;
}
- // Check if the configuration is set in the workspace.
- const useLanguageServer = getGoConfig().inspect('useLanguageServer');
- let workspace: boolean;
- if (useLanguageServer.workspaceFolderValue === false || useLanguageServer.workspaceValue === false) {
- workspace = true;
- }
// Prompt the user to enable gopls and record what actions they took.
- let optOutCfg = getGoplsOptOutConfig(workspace);
- optOutCfg = await promptAboutGoplsOptOut(optOutCfg);
- flushGoplsOptOutConfig(optOutCfg, workspace);
+ await promptAboutGoplsOptOut(false);
// Check if the language server has now been enabled, and if so,
// it will be installed below.
cfg = buildLanguageServerConfig(getGoConfig());
@@ -232,6 +224,76 @@
setTimeout(survey, 30 * timeMinute);
}
+export async function promptAboutGoplsOptOut(surveyOnly: boolean) {
+ // Check if the configuration is set in the workspace.
+ const useLanguageServer = getGoConfig().inspect('useLanguageServer');
+ const workspace = useLanguageServer.workspaceFolderValue === false || useLanguageServer.workspaceValue === false;
+
+ let cfg = getGoplsOptOutConfig(workspace);
+ const promptFn = async (): Promise<GoplsOptOutConfig> => {
+ if (cfg.prompt === false) {
+ return cfg;
+ }
+ // Prompt the user ~once a month.
+ if (cfg.lastDatePrompted && daysBetween(new Date(), cfg.lastDatePrompted) < 30) {
+ return cfg;
+ }
+ cfg.lastDatePrompted = new Date();
+ if (surveyOnly) {
+ await promptForGoplsOptOutSurvey(cfg, `Looks like you've disabled the Go language server, which is the recommended default for this extension.
+Would you be willing to tell us why you've disabled it?`);
+ return cfg;
+ }
+ const selected = await vscode.window.showInformationMessage(`We noticed that you have disabled the language server.
+It has [stabilized](https://blog.golang.org/gopls-vscode-go) and is now enabled by default in this extension.
+Would you like to enable it now?`, { title: 'Enable' }, { title: 'Not now' }, { title: 'Never' });
+ if (!selected) {
+ return cfg;
+ }
+ switch (selected.title) {
+ case 'Enable':
+ // Change the user's Go configuration to enable the language server.
+ // Remove the setting entirely, since it's on by default now.
+ const goConfig = getGoConfig();
+ await goConfig.update('useLanguageServer', undefined, vscode.ConfigurationTarget.Global);
+ if (goConfig.inspect('useLanguageServer').workspaceValue === false) {
+ await goConfig.update('useLanguageServer', undefined, vscode.ConfigurationTarget.Workspace);
+ }
+ if (goConfig.inspect('useLanguageServer').workspaceFolderValue === false) {
+ await goConfig.update('useLanguageServer', undefined, vscode.ConfigurationTarget.WorkspaceFolder);
+ }
+ cfg.prompt = false;
+ break;
+ case 'Not now':
+ cfg.prompt = true;
+ break;
+ case 'Never':
+ cfg.prompt = false;
+ await promptForGoplsOptOutSurvey(cfg, `No problem. Would you be willing to tell us why you have opted out of the language server?`);
+ break;
+ }
+ return cfg;
+ };
+ cfg = await promptFn();
+ flushGoplsOptOutConfig(cfg, workspace);
+}
+
+async function promptForGoplsOptOutSurvey(cfg: GoplsOptOutConfig, msg: string): Promise<GoplsOptOutConfig> {
+ const s = await vscode.window.showInformationMessage(msg, { title: 'Yes' }, { title: 'No' });
+ if (!s) {
+ return cfg;
+ }
+ switch (s.title) {
+ case 'Yes':
+ cfg.prompt = false;
+ await vscode.env.openExternal(vscode.Uri.parse(`https://forms.gle/hwC8CncV7Cyc2yBN6`));
+ break;
+ case 'No':
+ break;
+ }
+ return cfg;
+}
+
export interface GoplsOptOutConfig {
prompt?: boolean;
lastDatePrompted?: Date;
@@ -239,9 +301,9 @@
const goplsOptOutConfigKey = 'goplsOptOutConfig';
-function getGoplsOptOutConfig(workspace: boolean): GoplsOptOutConfig {
+export const getGoplsOptOutConfig = (workspace: boolean): GoplsOptOutConfig => {
return getStateConfig(goplsOptOutConfigKey, workspace) as GoplsOptOutConfig;
-}
+};
function flushGoplsOptOutConfig(cfg: GoplsOptOutConfig, workspace: boolean) {
if (workspace) {
@@ -250,58 +312,6 @@
updateGlobalState(goplsOptOutConfigKey, JSON.stringify(cfg));
}
-export async function promptAboutGoplsOptOut(cfg: GoplsOptOutConfig): Promise<GoplsOptOutConfig> {
- if (cfg.prompt === false) {
- return cfg;
- }
- // Prompt the user ~once a month.
- if (cfg.lastDatePrompted && daysBetween(new Date(), cfg.lastDatePrompted) < 30) {
- return cfg;
- }
- cfg.lastDatePrompted = new Date();
- const selected = await vscode.window.showInformationMessage(`We noticed that you have disabled the language server.
-It has [stabilized](https://blog.golang.org/gopls-vscode-go) and is now enabled by default in this extension.
-Would you like to enable it now?`, { title: 'Enable' }, { title: 'Not now' }, { title: 'Never' });
- if (!selected) {
- return cfg;
- }
- switch (selected.title) {
- case 'Enable':
- // Change the user's Go configuration to enable the language server.
- // Remove the setting entirely, since it's on by default now.
- const goConfig = getGoConfig();
- await goConfig.update('useLanguageServer', undefined, vscode.ConfigurationTarget.Global);
- if (goConfig.inspect('useLanguageServer').workspaceValue === false) {
- await goConfig.update('useLanguageServer', undefined, vscode.ConfigurationTarget.Workspace);
- }
- if (goConfig.inspect('useLanguageServer').workspaceFolderValue === false) {
- await goConfig.update('useLanguageServer', undefined, vscode.ConfigurationTarget.WorkspaceFolder);
- }
-
- cfg.prompt = false;
- break;
- case 'Not now':
- cfg.prompt = true;
- break;
- case 'Never':
- cfg.prompt = false;
- await promptForGoplsOptOutSurvey();
- break;
- }
- return cfg;
-}
-
-async function promptForGoplsOptOutSurvey() {
- const selected = await vscode.window.showInformationMessage(`No problem. Would you be willing to tell us why you have opted out of the language server?`, { title: 'Yes' }, { title: 'No' });
- switch (selected.title) {
- case 'Yes':
- await vscode.env.openExternal(vscode.Uri.parse(`https://forms.gle/hwC8CncV7Cyc2yBN6`));
- break;
- case 'No':
- break;
- }
-}
-
async function startLanguageServer(ctx: vscode.ExtensionContext, config: LanguageServerConfig): Promise<boolean> {
// If the client has already been started, make sure to clear existing
// diagnostics and stop it.
@@ -786,7 +796,7 @@
defaultLanguageProviders = [];
}
-export function watchLanguageServerConfiguration(e: vscode.ConfigurationChangeEvent) {
+export async function watchLanguageServerConfiguration(e: vscode.ConfigurationChangeEvent) {
if (!e.affectsConfiguration('go')) {
return;
}
@@ -801,6 +811,10 @@
) {
restartLanguageServer();
}
+
+ if (e.affectsConfiguration('go.useLanguageServer') && getGoConfig()['useLanguageServer'] === false) {
+ promptAboutGoplsOptOut(true);
+ }
}
export function buildLanguageServerConfig(goConfig: vscode.WorkspaceConfiguration): LanguageServerConfig {
diff --git a/test/gopls/survey.test.ts b/test/gopls/survey.test.ts
index 3e667db..405c6af 100644
--- a/test/gopls/survey.test.ts
+++ b/test/gopls/survey.test.ts
@@ -6,12 +6,12 @@
import * as assert from 'assert';
import sinon = require('sinon');
import vscode = require('vscode');
-import { GoplsOptOutConfig, promptAboutGoplsOptOut, shouldPromptForGoplsSurvey, SurveyConfig } from '../../src/goLanguageServer';
+import goLanguageServer = require('../../src/goLanguageServer');
suite('gopls survey tests', () => {
test('prompt for survey', () => {
// global state -> offer survey
- const testCases: [SurveyConfig, boolean][] = [
+ const testCases: [goLanguageServer.SurveyConfig, boolean][] = [
// User who is activating the extension for the first time.
[
{},
@@ -73,7 +73,7 @@
sinon.replace(Math, 'random', () => 0);
const now = new Date('2020-04-29');
- const gotPrompt = shouldPromptForGoplsSurvey(now, testConfig);
+ const gotPrompt = goLanguageServer.shouldPromptForGoplsSurvey(now, testConfig);
if (wantPrompt) {
assert.ok(gotPrompt, `prompt determination failed for ${i}`);
} else {
@@ -95,7 +95,7 @@
sandbox.restore();
});
- const testCases: [GoplsOptOutConfig, string, number][] = [
+ const testCases: [goLanguageServer.GoplsOptOutConfig, string, number][] = [
// No saved config, different choices in the first dialog box.
[{}, 'Enable', 1],
[{}, 'Not now', 1],
@@ -110,10 +110,11 @@
testCases.map(async ([testConfig, choice, wantCount], i) => {
test(`opt out: ${i}`, async () => {
const stub = sandbox.stub(vscode.window, 'showInformationMessage').resolves({ title: choice });
+ const getGoplsOptOutConfigStub = sandbox.stub(goLanguageServer, 'getGoplsOptOutConfig').returns(testConfig);
- await promptAboutGoplsOptOut(testConfig);
+ await goLanguageServer.promptAboutGoplsOptOut(false);
assert.strictEqual(stub.callCount, wantCount);
-
+ sandbox.assert.called(getGoplsOptOutConfigStub);
});
});
});