From bb2e86948956562bc98d94f65c1d03a718461ee1 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 24 Jul 2017 18:01:11 -0700 Subject: [PATCH] Show multiple node_modules versions in TSVersion picker --- .../typescript/src/utils/versionPicker.ts | 87 +++++++++---------- .../typescript/src/utils/versionProvider.ts | 40 +++++++-- 2 files changed, 73 insertions(+), 54 deletions(-) diff --git a/extensions/typescript/src/utils/versionPicker.ts b/extensions/typescript/src/utils/versionPicker.ts index 22d4e0a1700..b978b2ef12b 100644 --- a/extensions/typescript/src/utils/versionPicker.ts +++ b/extensions/typescript/src/utils/versionPicker.ts @@ -5,7 +5,7 @@ import * as nls from 'vscode-nls'; import { TypeScriptVersionProvider, TypeScriptVersion } from "./versionProvider"; -import { Memento, commands, Uri, window, QuickPickItem } from "vscode"; +import { Memento, commands, Uri, window, QuickPickItem, workspace } from "vscode"; const localize = nls.loadMessageBundle(); @@ -13,6 +13,7 @@ const useWorkspaceTsdkStorageKey = 'typescript.useWorkspaceTsdk'; interface MyQuickPickItem extends QuickPickItem { id: MessageAction; + version?: TypeScriptVersion; } enum MessageAction { @@ -31,7 +32,7 @@ export class TypeScriptVersionPicker { this._currentVersion = this.versionProvider.defaultVersion; if (workspaceState.get(useWorkspaceTsdkStorageKey, false)) { - const localVersion = this.versionProvider.localVersion; + const localVersion = this.versionProvider.localTsdkVersion; if (localVersion) { this._currentVersion = localVersion; } @@ -46,15 +47,12 @@ export class TypeScriptVersionPicker { this._currentVersion = this.versionProvider.bundledVersion; } - public show(firstRun?: boolean): Thenable<{ oldVersion?: TypeScriptVersion, newVersion?: TypeScriptVersion }> { - const useWorkspaceVersionSetting = this.workspaceState.get(useWorkspaceTsdkStorageKey, false); - const shippedVersion = this.versionProvider.defaultVersion; - const localVersion = this.versionProvider.localVersion; - + public async show(firstRun?: boolean): Promise<{ oldVersion?: TypeScriptVersion, newVersion?: TypeScriptVersion }> { const pickOptions: MyQuickPickItem[] = []; + const shippedVersion = this.versionProvider.defaultVersion; pickOptions.push({ - label: (this.currentVersion.path === shippedVersion.path && (this.currentVersion.path !== (localVersion && localVersion.path) || !useWorkspaceVersionSetting) + label: (this.currentVersion.path === shippedVersion.path ? '• ' : '') + localize('useVSCodeVersionOption', 'Use VSCode\'s Version'), description: shippedVersion.version.versionString, @@ -62,14 +60,15 @@ export class TypeScriptVersionPicker { id: MessageAction.useBundled }); - if (localVersion) { + for (const version of this.versionProvider.localVersions) { pickOptions.push({ - label: ((this.currentVersion.path === localVersion.path && (this.currentVersion.path !== shippedVersion.path || useWorkspaceVersionSetting) + label: (this.currentVersion.path === version.path ? '• ' - : '')) + localize('useWorkspaceVersionOption', 'Use Workspace Version'), - description: localVersion.version.versionString, - detail: localVersion.label, - id: MessageAction.useLocal + : '') + localize('useWorkspaceVersionOption', 'Use Workspace Version'), + description: version.version.versionString, + detail: version.label, + id: MessageAction.useLocal, + version: version }); } @@ -79,45 +78,43 @@ export class TypeScriptVersionPicker { id: MessageAction.learnMore }); - return window.showQuickPick(pickOptions, { + const selected = await window.showQuickPick(pickOptions, { placeHolder: localize( 'selectTsVersion', 'Select the TypeScript version used for JavaScript and TypeScript language features'), ignoreFocusOut: firstRun - }) - .then(selected => { - if (!selected) { - return { oldVersion: this.currentVersion }; + }); + + if (!selected) { + return { oldVersion: this.currentVersion }; + } + + switch (selected.id) { + case MessageAction.useLocal: + await this.workspaceState.update(useWorkspaceTsdkStorageKey, true); + if (selected.version) { + const tsConfig = workspace.getConfiguration('typescript'); + await tsConfig.update('tsdk', selected.version.label, false); + + const previousVersion = this.currentVersion; + this._currentVersion = selected.version; + return { oldVersion: previousVersion, newVersion: selected.version }; } - switch (selected.id) { - case MessageAction.useLocal: - return this.workspaceState.update(useWorkspaceTsdkStorageKey, true) - .then(_ => { - if (localVersion) { - const previousVersion = this.currentVersion; + return { oldVersion: this.currentVersion }; - this._currentVersion = localVersion; - return { oldVersion: previousVersion, newVersion: localVersion }; - } - return { oldVersion: this.currentVersion }; - }); + case MessageAction.useBundled: + await this.workspaceState.update(useWorkspaceTsdkStorageKey, false); + const previousVersion = this.currentVersion; + this._currentVersion = shippedVersion; + return { oldVersion: previousVersion, newVersion: shippedVersion }; - case MessageAction.useBundled: - return this.workspaceState.update(useWorkspaceTsdkStorageKey, false) - .then(_ => { - const previousVersion = this.currentVersion; - this._currentVersion = shippedVersion; - return { oldVersion: previousVersion, newVersion: shippedVersion }; - }); - case MessageAction.learnMore: - commands.executeCommand('vscode.open', Uri.parse('https://go.microsoft.com/fwlink/?linkid=839919')); - return { oldVersion: this.currentVersion }; - - default: - return { oldVersion: this.currentVersion }; - } - }); + case MessageAction.learnMore: + commands.executeCommand('vscode.open', Uri.parse('https://go.microsoft.com/fwlink/?linkid=839919')); + return { oldVersion: this.currentVersion }; + default: + return { oldVersion: this.currentVersion }; + } } } \ No newline at end of file diff --git a/extensions/typescript/src/utils/versionProvider.ts b/extensions/typescript/src/utils/versionProvider.ts index 02698ded04c..3e5e577e90c 100644 --- a/extensions/typescript/src/utils/versionProvider.ts +++ b/extensions/typescript/src/utils/versionProvider.ts @@ -44,19 +44,36 @@ export class TypeScriptVersionProvider { return undefined; } - public get localVersion(): TypeScriptVersion | undefined { + public get localTsdkVersion(): TypeScriptVersion | undefined { const tsdkVersions = this.localTsdkVersions; if (tsdkVersions && tsdkVersions.length) { return tsdkVersions[0]; } const nodeVersions = this.localNodeModulesVersions; - if (nodeVersions && nodeVersions.length) { + if (nodeVersions && nodeVersions.length === 1) { return nodeVersions[0]; } return undefined; } + public get localVersions(): TypeScriptVersion[] { + const versions: TypeScriptVersion[] = []; + const tsdkVersions = this.localTsdkVersions; + if (tsdkVersions && tsdkVersions.length) { + versions.push(tsdkVersions[0]); + } + + const paths = new Set(); + return versions.concat(this.localNodeModulesVersions).filter(x => { + if (paths.has(x.path)) { + return false; + } + paths.add(x.path); + return true; + }); + } + public get bundledVersion(): TypeScriptVersion { try { const bundledVersion = this.loadFromPath(require.resolve('typescript/lib/tsserver.js')); @@ -83,12 +100,17 @@ export class TypeScriptVersionProvider { } for (const root of workspace.workspaceFolders || []) { - const rootPrefix = `./${root.name}/`; - const winRootPrefix = `.\\${root.name}\\`; - - if (tsdkPathSetting.startsWith(rootPrefix) || tsdkPathSetting.startsWith(winRootPrefix)) { - const workspacePath = path.join(root.uri.fsPath, tsdkPathSetting.replace(rootPrefix, '')); - return this.getTypeScriptsFromPaths(workspacePath); + const rootPrefixes = [`./${root.name}/`, `${root.name}/`, `.\\${root.name}\\`, `${root.name}\\`]; + for (const rootPrefix of rootPrefixes) { + if (tsdkPathSetting.startsWith(rootPrefix)) { + const workspacePath = path.join(root.uri.fsPath, tsdkPathSetting.replace(rootPrefix, '')); + const version = this.loadFromPath(path.join(workspacePath, 'tsserver.js')); + if (version) { + version.label = tsdkPathSetting; + return [version]; + } + return []; + } } } @@ -110,7 +132,7 @@ export class TypeScriptVersionProvider { } const versions: TypeScriptVersion[] = []; - for (const root of [workspace.workspaceFolders[0]]) { + for (const root of workspace.workspaceFolders) { const p = path.join(root.uri.fsPath, typeScriptPath, 'tsserver.js'); let label: string | undefined = undefined;