TS: Add setting to prompt users about workspace tsdk (#95566)
* add a setting to prompt users to switch to tsdk version * version manager in control Co-authored-by: Duncan Walter <dwalter@hubspot.com>
This commit is contained in:
parent
4b178bfc9f
commit
c7c2301bc2
|
@ -140,6 +140,12 @@
|
||||||
"usesOnlineServices"
|
"usesOnlineServices"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"typescript.enablePromptUseWorkspaceTsdk": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "%typescript.enablePromptUseWorkspaceTsdk%",
|
||||||
|
"scope": "window"
|
||||||
|
},
|
||||||
"typescript.npm": {
|
"typescript.npm": {
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
"configuration.suggest.includeAutomaticOptionalChainCompletions": "Enable/disable showing completions on potentially undefined values that insert an optional chain call. Requires TS 3.7+ and strict null checks to be enabled.",
|
"configuration.suggest.includeAutomaticOptionalChainCompletions": "Enable/disable showing completions on potentially undefined values that insert an optional chain call. Requires TS 3.7+ and strict null checks to be enabled.",
|
||||||
"typescript.tsdk.desc": "Specifies the folder path to the tsserver and lib*.d.ts files under a TypeScript install to use for IntelliSense, for example: `./node_modules/typescript/lib`.\n\n- When specified as a user setting, the TypeScript version from `typescript.tsdk` automatically replaces the built-in TypeScript version.\n- When specified as a workspace setting, `typescript.tsdk` allows you to switch to use that workspace version of TypeScript for IntelliSense with the `TypeScript: Select TypeScript version` command.\n\nSee the [TypeScript documentation](https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-newer-typescript-versions) for more detail about managing TypeScript versions.",
|
"typescript.tsdk.desc": "Specifies the folder path to the tsserver and lib*.d.ts files under a TypeScript install to use for IntelliSense, for example: `./node_modules/typescript/lib`.\n\n- When specified as a user setting, the TypeScript version from `typescript.tsdk` automatically replaces the built-in TypeScript version.\n- When specified as a workspace setting, `typescript.tsdk` allows you to switch to use that workspace version of TypeScript for IntelliSense with the `TypeScript: Select TypeScript version` command.\n\nSee the [TypeScript documentation](https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-newer-typescript-versions) for more detail about managing TypeScript versions.",
|
||||||
"typescript.disableAutomaticTypeAcquisition": "Disables automatic type acquisition. Automatic type acquisition fetches `@types` packages from npm to improve IntelliSense for external libraries.",
|
"typescript.disableAutomaticTypeAcquisition": "Disables automatic type acquisition. Automatic type acquisition fetches `@types` packages from npm to improve IntelliSense for external libraries.",
|
||||||
|
"typescript.enablePromptUseWorkspaceTsdk": "Enables prompting of users to use the TypeScript version configured in the workspace for Intellisense.",
|
||||||
"typescript.tsserver.log": "Enables logging of the TS server to a file. This log can be used to diagnose TS Server issues. The log may contain file paths, source code, and other potentially sensitive information from your project.",
|
"typescript.tsserver.log": "Enables logging of the TS server to a file. This log can be used to diagnose TS Server issues. The log may contain file paths, source code, and other potentially sensitive information from your project.",
|
||||||
"typescript.tsserver.pluginPaths": "Additional paths to discover TypeScript Language Service plugins. Requires using TypeScript 2.3.0 or newer in the workspace.",
|
"typescript.tsserver.pluginPaths": "Additional paths to discover TypeScript Language Service plugins. Requires using TypeScript 2.3.0 or newer in the workspace.",
|
||||||
"typescript.tsserver.pluginPaths.item": "Either an absolute or relative path. Relative path will be resolved against workspace folder(s).",
|
"typescript.tsserver.pluginPaths.item": "Either an absolute or relative path. Relative path will be resolved against workspace folder(s).",
|
||||||
|
|
|
@ -140,7 +140,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||||
this._configuration = TypeScriptServiceConfiguration.loadFromWorkspace();
|
this._configuration = TypeScriptServiceConfiguration.loadFromWorkspace();
|
||||||
this.versionProvider = new TypeScriptVersionProvider(this._configuration);
|
this.versionProvider = new TypeScriptVersionProvider(this._configuration);
|
||||||
this.pluginPathsProvider = new TypeScriptPluginPathsProvider(this._configuration);
|
this.pluginPathsProvider = new TypeScriptPluginPathsProvider(this._configuration);
|
||||||
this._versionManager = this._register(new TypeScriptVersionManager(this.versionProvider, this.workspaceState));
|
this._versionManager = this._register(new TypeScriptVersionManager(this._configuration, this.versionProvider, this.workspaceState));
|
||||||
this._register(this._versionManager.onDidPickNewVersion(() => {
|
this._register(this._versionManager.onDidPickNewVersion(() => {
|
||||||
this.restartTsServer();
|
this.restartTsServer();
|
||||||
}));
|
}));
|
||||||
|
@ -163,6 +163,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||||
this._configuration = TypeScriptServiceConfiguration.loadFromWorkspace();
|
this._configuration = TypeScriptServiceConfiguration.loadFromWorkspace();
|
||||||
|
|
||||||
this.versionProvider.updateConfiguration(this._configuration);
|
this.versionProvider.updateConfiguration(this._configuration);
|
||||||
|
this._versionManager.updateConfiguration(this._configuration);
|
||||||
this.pluginPathsProvider.updateConfiguration(this._configuration);
|
this.pluginPathsProvider.updateConfiguration(this._configuration);
|
||||||
this.tracer.updateConfiguration();
|
this.tracer.updateConfiguration();
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ export class TypeScriptServiceConfiguration {
|
||||||
public readonly useSeparateSyntaxServer: boolean;
|
public readonly useSeparateSyntaxServer: boolean;
|
||||||
public readonly enableProjectDiagnostics: boolean;
|
public readonly enableProjectDiagnostics: boolean;
|
||||||
public readonly maxTsServerMemory: number;
|
public readonly maxTsServerMemory: number;
|
||||||
|
public readonly enablePromptUseWorkspaceTsdk: boolean;
|
||||||
public readonly watchOptions: protocol.WatchOptions | undefined;
|
public readonly watchOptions: protocol.WatchOptions | undefined;
|
||||||
|
|
||||||
public static loadFromWorkspace(): TypeScriptServiceConfiguration {
|
public static loadFromWorkspace(): TypeScriptServiceConfiguration {
|
||||||
|
@ -80,6 +81,7 @@ export class TypeScriptServiceConfiguration {
|
||||||
this.useSeparateSyntaxServer = TypeScriptServiceConfiguration.readUseSeparateSyntaxServer(configuration);
|
this.useSeparateSyntaxServer = TypeScriptServiceConfiguration.readUseSeparateSyntaxServer(configuration);
|
||||||
this.enableProjectDiagnostics = TypeScriptServiceConfiguration.readEnableProjectDiagnostics(configuration);
|
this.enableProjectDiagnostics = TypeScriptServiceConfiguration.readEnableProjectDiagnostics(configuration);
|
||||||
this.maxTsServerMemory = TypeScriptServiceConfiguration.readMaxTsServerMemory(configuration);
|
this.maxTsServerMemory = TypeScriptServiceConfiguration.readMaxTsServerMemory(configuration);
|
||||||
|
this.enablePromptUseWorkspaceTsdk = TypeScriptServiceConfiguration.readEnablePromptUseWorkspaceTsdk(configuration);
|
||||||
this.watchOptions = TypeScriptServiceConfiguration.readWatchOptions(configuration);
|
this.watchOptions = TypeScriptServiceConfiguration.readWatchOptions(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +98,8 @@ export class TypeScriptServiceConfiguration {
|
||||||
&& this.useSeparateSyntaxServer === other.useSeparateSyntaxServer
|
&& this.useSeparateSyntaxServer === other.useSeparateSyntaxServer
|
||||||
&& this.enableProjectDiagnostics === other.enableProjectDiagnostics
|
&& this.enableProjectDiagnostics === other.enableProjectDiagnostics
|
||||||
&& this.maxTsServerMemory === other.maxTsServerMemory
|
&& this.maxTsServerMemory === other.maxTsServerMemory
|
||||||
&& objects.equals(this.watchOptions, other.watchOptions);
|
&& objects.equals(this.watchOptions, other.watchOptions)
|
||||||
|
&& this.enablePromptUseWorkspaceTsdk === other.enablePromptUseWorkspaceTsdk;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static fixPathPrefixes(inspectValue: string): string {
|
private static fixPathPrefixes(inspectValue: string): string {
|
||||||
|
@ -175,4 +178,8 @@ export class TypeScriptServiceConfiguration {
|
||||||
}
|
}
|
||||||
return Math.max(memoryInMB, minimumMaxMemory);
|
return Math.max(memoryInMB, minimumMaxMemory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readEnablePromptUseWorkspaceTsdk(configuration: vscode.WorkspaceConfiguration): boolean {
|
||||||
|
return configuration.get<boolean>('typescript.enablePromptUseWorkspaceTsdk', false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,12 @@ import * as vscode from 'vscode';
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
import { TypeScriptVersion, TypeScriptVersionProvider } from './versionProvider';
|
import { TypeScriptVersion, TypeScriptVersionProvider } from './versionProvider';
|
||||||
import { Disposable } from './dispose';
|
import { Disposable } from './dispose';
|
||||||
|
import { TypeScriptServiceConfiguration } from '../utils/configuration';
|
||||||
|
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
const useWorkspaceTsdkStorageKey = 'typescript.useWorkspaceTsdk';
|
const useWorkspaceTsdkStorageKey = 'typescript.useWorkspaceTsdk';
|
||||||
|
const suppressPromptWorkspaceTsdkStorageKey = 'typescript.suppressPromptWorkspaceTsdk';
|
||||||
|
|
||||||
interface QuickPickItem extends vscode.QuickPickItem {
|
interface QuickPickItem extends vscode.QuickPickItem {
|
||||||
run(): void;
|
run(): void;
|
||||||
|
@ -21,6 +23,7 @@ export class TypeScriptVersionManager extends Disposable {
|
||||||
private _currentVersion: TypeScriptVersion;
|
private _currentVersion: TypeScriptVersion;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
|
private configuration: TypeScriptServiceConfiguration,
|
||||||
private readonly versionProvider: TypeScriptVersionProvider,
|
private readonly versionProvider: TypeScriptVersionProvider,
|
||||||
private readonly workspaceState: vscode.Memento
|
private readonly workspaceState: vscode.Memento
|
||||||
) {
|
) {
|
||||||
|
@ -34,11 +37,30 @@ export class TypeScriptVersionManager extends Disposable {
|
||||||
this._currentVersion = localVersion;
|
this._currentVersion = localVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.isInPromptWorkspaceTsdkState(configuration)) {
|
||||||
|
setImmediate(() => {
|
||||||
|
this.promptUseWorkspaceTsdk();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly _onDidPickNewVersion = this._register(new vscode.EventEmitter<void>());
|
private readonly _onDidPickNewVersion = this._register(new vscode.EventEmitter<void>());
|
||||||
public readonly onDidPickNewVersion = this._onDidPickNewVersion.event;
|
public readonly onDidPickNewVersion = this._onDidPickNewVersion.event;
|
||||||
|
|
||||||
|
public updateConfiguration(nextConfiguration: TypeScriptServiceConfiguration) {
|
||||||
|
const lastConfiguration = this.configuration;
|
||||||
|
this.configuration = nextConfiguration;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!this.isInPromptWorkspaceTsdkState(lastConfiguration)
|
||||||
|
&& this.isInPromptWorkspaceTsdkState(nextConfiguration)
|
||||||
|
) {
|
||||||
|
this.promptUseWorkspaceTsdk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public get currentVersion(): TypeScriptVersion {
|
public get currentVersion(): TypeScriptVersion {
|
||||||
return this._currentVersion;
|
return this._currentVersion;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +93,7 @@ export class TypeScriptVersionManager extends Disposable {
|
||||||
detail: bundledVersion.pathLabel,
|
detail: bundledVersion.pathLabel,
|
||||||
run: async () => {
|
run: async () => {
|
||||||
await this.workspaceState.update(useWorkspaceTsdkStorageKey, false);
|
await this.workspaceState.update(useWorkspaceTsdkStorageKey, false);
|
||||||
this.updateForPickedVersion(bundledVersion);
|
this.updateActiveVersion(bundledVersion);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -88,13 +110,38 @@ export class TypeScriptVersionManager extends Disposable {
|
||||||
await this.workspaceState.update(useWorkspaceTsdkStorageKey, true);
|
await this.workspaceState.update(useWorkspaceTsdkStorageKey, true);
|
||||||
const tsConfig = vscode.workspace.getConfiguration('typescript');
|
const tsConfig = vscode.workspace.getConfiguration('typescript');
|
||||||
await tsConfig.update('tsdk', version.pathLabel, false);
|
await tsConfig.update('tsdk', version.pathLabel, false);
|
||||||
this.updateForPickedVersion(version);
|
this.updateActiveVersion(version);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateForPickedVersion(pickedVersion: TypeScriptVersion) {
|
private async promptUseWorkspaceTsdk(): Promise<void> {
|
||||||
|
const workspaceVersion = this.versionProvider.localVersion;
|
||||||
|
|
||||||
|
if (workspaceVersion === undefined) {
|
||||||
|
throw new Error('Could not prompt to use workspace TypeScript version because no workspace version is specified');
|
||||||
|
}
|
||||||
|
|
||||||
|
const allowIt = localize('allow', 'Allow');
|
||||||
|
const dismissPrompt = localize('dismiss', 'Dismiss');
|
||||||
|
const suppressPrompt = localize('suppress prompt', 'Never in this Workspace');
|
||||||
|
|
||||||
|
const result = await vscode.window.showInformationMessage(localize('promptUseWorkspaceTsdk', 'This workspace contains a TypeScript version. Would you like to use the workspace TypeScript version for TypeScript and JavaScript language features?'),
|
||||||
|
allowIt,
|
||||||
|
dismissPrompt,
|
||||||
|
suppressPrompt
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result === allowIt) {
|
||||||
|
await this.workspaceState.update(useWorkspaceTsdkStorageKey, true);
|
||||||
|
this.updateActiveVersion(workspaceVersion);
|
||||||
|
} else if (result === suppressPrompt) {
|
||||||
|
await this.workspaceState.update(suppressPromptWorkspaceTsdkStorageKey, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateActiveVersion(pickedVersion: TypeScriptVersion) {
|
||||||
const oldVersion = this.currentVersion;
|
const oldVersion = this.currentVersion;
|
||||||
this._currentVersion = pickedVersion;
|
this._currentVersion = pickedVersion;
|
||||||
if (!oldVersion.eq(pickedVersion)) {
|
if (!oldVersion.eq(pickedVersion)) {
|
||||||
|
@ -105,6 +152,19 @@ export class TypeScriptVersionManager extends Disposable {
|
||||||
private get useWorkspaceTsdkSetting(): boolean {
|
private get useWorkspaceTsdkSetting(): boolean {
|
||||||
return this.workspaceState.get<boolean>(useWorkspaceTsdkStorageKey, false);
|
return this.workspaceState.get<boolean>(useWorkspaceTsdkStorageKey, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get suppressPromptWorkspaceTsdkSetting(): boolean {
|
||||||
|
return this.workspaceState.get<boolean>(suppressPromptWorkspaceTsdkStorageKey, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private isInPromptWorkspaceTsdkState(configuration: TypeScriptServiceConfiguration) {
|
||||||
|
return (
|
||||||
|
configuration.localTsdk !== null
|
||||||
|
&& configuration.enablePromptUseWorkspaceTsdk === true
|
||||||
|
&& this.suppressPromptWorkspaceTsdkSetting === false
|
||||||
|
&& this.useWorkspaceTsdkSetting === false
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const LearnMorePickItem: QuickPickItem = {
|
const LearnMorePickItem: QuickPickItem = {
|
||||||
|
|
Loading…
Reference in a new issue