From fcc10f37c2231307d679432021244c51e4779a4b Mon Sep 17 00:00:00 2001 From: lramos15 Date: Mon, 8 Jul 2019 09:15:36 -0700 Subject: [PATCH 01/19] Resolved terminal argds --- .../contrib/terminal/common/terminalEnvironment.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index db22a46964de1..011ec3be6ee51 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -235,6 +235,17 @@ export function createTerminalEnvironment( if (shellLaunchConfig.env) { resolveConfigurationVariables(configurationResolverService, shellLaunchConfig.env, lastActiveWorkspace); } + if (shellLaunchConfig.args) { + if (Array.isArray(shellLaunchConfig.args)) { + const resolvedArgs: string[] = []; + for (const arg of shellLaunchConfig.args) { + resolvedArgs.push(configurationResolverService.resolve(undefined, arg)); + } + shellLaunchConfig.args = resolvedArgs; + } else { + shellLaunchConfig.args = configurationResolverService.resolve(undefined, shellLaunchConfig.args); + } + } } // Merge config (settings) and ShellLaunchConfig environments From 2e00ccace7f9f58d14c3af7a72f68a3ca02db37a Mon Sep 17 00:00:00 2001 From: lramos15 Date: Mon, 8 Jul 2019 13:59:30 -0700 Subject: [PATCH 02/19] Move location of resolution --- .../api/browser/mainThreadTerminalService.ts | 16 +++++----- .../workbench/api/common/extHost.protocol.ts | 5 ++-- src/vs/workbench/api/node/extHost.api.impl.ts | 2 +- .../api/node/extHostTerminalService.ts | 22 +++++++------- .../tasks/browser/terminalTaskSystem.ts | 2 +- .../contrib/terminal/browser/terminal.ts | 3 +- .../browser/terminalProcessManager.ts | 2 +- .../terminal/common/terminalEnvironment.ts | 30 ++++++++++--------- .../terminalInstanceService.ts | 5 +++- 9 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 7883f70b7b651..becfbf686547d 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -11,6 +11,7 @@ import { URI } from 'vs/base/common/uri'; import { StopWatch } from 'vs/base/common/stopwatch'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; +import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; @extHostNamedCustomer(MainContext.MainThreadTerminalService) export class MainThreadTerminalService implements MainThreadTerminalServiceShape { @@ -27,7 +28,8 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape extHostContext: IExtHostContext, @ITerminalService private readonly _terminalService: ITerminalService, @ITerminalInstanceService readonly terminalInstanceService: ITerminalInstanceService, - @IRemoteAgentService readonly _remoteAgentService: IRemoteAgentService + @IRemoteAgentService readonly _remoteAgentService: IRemoteAgentService, + @IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTerminalService); this._remoteAuthority = extHostContext.remoteAuthority; @@ -47,7 +49,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._toDispose.add(_terminalService.onInstanceProcessIdReady(instance => this._onTerminalProcessIdReady(instance))); this._toDispose.add(_terminalService.onInstanceDimensionsChanged(instance => this._onInstanceDimensionsChanged(instance))); this._toDispose.add(_terminalService.onInstanceMaximumDimensionsChanged(instance => this._onInstanceMaximumDimensionsChanged(instance))); - this._toDispose.add(_terminalService.onInstanceRequestExtHostProcess(request => this._onTerminalRequestExtHostProcess(request))); + this._toDispose.add(_terminalService.onInstanceRequestExtHostProcess(request => this._onTerminalRequestExtHostProcess(request, this._configurationResolverService))); this._toDispose.add(_terminalService.onInstanceRequestVirtualProcess(proxy => this._onTerminalRequestVirtualProcess(proxy))); this._toDispose.add(_terminalService.onActiveInstanceChanged(instance => this._onActiveTerminalChanged(instance ? instance.id : null))); this._toDispose.add(_terminalService.onInstanceTitleChanged(instance => this._onTitleChanged(instance.id, instance.title))); @@ -56,7 +58,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape // ITerminalInstanceService listeners if (terminalInstanceService.onRequestDefaultShellAndArgs) { - this._toDispose.add(terminalInstanceService.onRequestDefaultShellAndArgs(e => this._onRequestDefaultShellAndArgs(e))); + this._toDispose.add(terminalInstanceService.onRequestDefaultShellAndArgs(e => this._onRequestDefaultShellAndArgs(e, this._configurationResolverService))); } // Set initial ext host state @@ -238,7 +240,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._proxy.$acceptTerminalMaximumDimensions(instance.id, instance.maxCols, instance.maxRows); } - private _onTerminalRequestExtHostProcess(request: ITerminalProcessExtHostRequest): void { + private _onTerminalRequestExtHostProcess(request: ITerminalProcessExtHostRequest, configurationResolverService: IConfigurationResolverService): void { // Only allow processes on remote ext hosts if (!this._remoteAuthority) { return; @@ -258,7 +260,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape cwd: request.shellLaunchConfig.cwd, env: request.shellLaunchConfig.env }; - this._proxy.$createProcess(request.proxy.terminalId, shellLaunchConfigDto, request.activeWorkspaceRootUri, request.cols, request.rows, request.isWorkspaceShellAllowed); + this._proxy.$createProcess(request.proxy.terminalId, shellLaunchConfigDto, request.activeWorkspaceRootUri, request.cols, request.rows, request.isWorkspaceShellAllowed, configurationResolverService); request.proxy.onInput(data => this._proxy.$acceptProcessInput(request.proxy.terminalId, data)); request.proxy.onResize(dimensions => this._proxy.$acceptProcessResize(request.proxy.terminalId, dimensions.cols, dimensions.rows)); request.proxy.onShutdown(immediate => this._proxy.$acceptProcessShutdown(request.proxy.terminalId, immediate)); @@ -341,9 +343,9 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } } - private _onRequestDefaultShellAndArgs(request: IDefaultShellAndArgsRequest): void { + private _onRequestDefaultShellAndArgs(request: IDefaultShellAndArgsRequest, configurationResolverService: IConfigurationResolverService): void { if (this._isPrimaryExtHost()) { - this._proxy.$requestDefaultShellAndArgs().then(e => request(e.shell, e.args)); + this._proxy.$requestDefaultShellAndArgs(configurationResolverService).then(e => request(e.shell, e.args)); } } } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 1f2802ea39064..ab73ef8a756ad 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -47,6 +47,7 @@ import { IRelativePattern } from 'vs/base/common/glob'; import { IRemoteConsoleLog } from 'vs/base/common/console'; import { VSBuffer } from 'vs/base/common/buffer'; import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; +import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; export interface IEnvironment { isExtensionDevelopmentDebug: boolean; @@ -1161,7 +1162,7 @@ export interface ExtHostTerminalServiceShape { $acceptTerminalTitleChange(id: number, name: string): void; $acceptTerminalDimensions(id: number, cols: number, rows: number): void; $acceptTerminalMaximumDimensions(id: number, cols: number, rows: number): void; - $createProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, activeWorkspaceRootUri: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void; + $createProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, activeWorkspaceRootUri: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean, configurationResolverService: IConfigurationResolverService): void; $acceptProcessInput(id: number, data: string): void; $acceptProcessResize(id: number, cols: number, rows: number): void; $acceptProcessShutdown(id: number, immediate: boolean): void; @@ -1170,7 +1171,7 @@ export interface ExtHostTerminalServiceShape { $acceptProcessRequestLatency(id: number): number; $acceptWorkspacePermissionsChanged(isAllowed: boolean): void; $requestAvailableShells(): Promise; - $requestDefaultShellAndArgs(): Promise; + $requestDefaultShellAndArgs(configurationResolverService: IConfigurationResolverService): Promise; } export interface ExtHostSCMShape { diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index debcbce5d4c76..7ba2ab81ce265 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -258,7 +258,7 @@ export function createApiFactory( return extHostClipboard; }, get shell() { - return extHostTerminalService.getDefaultShell(configProvider); + return extHostTerminalService.getDefaultShell(configProvider, undefined); }, openExternal(uri: URI) { return extHostWindow.openUri(uri, { allowTunneling: !!initData.remote.isRemote }); diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index ce45045e3755c..5e249af32f71d 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -23,6 +23,7 @@ import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocum import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal'; import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; import { IDisposable } from 'vs/base/common/lifecycle'; +import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; const RENDERER_NO_PROCESS_ID = -1; @@ -358,7 +359,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return renderer; } - public getDefaultShell(configProvider: ExtHostConfigProvider): string { + public getDefaultShell(configProvider: ExtHostConfigProvider, configurationResolverService?: IConfigurationResolverService): string { const fetchSetting = (key: string) => { const setting = configProvider .getConfiguration(key.substr(0, key.lastIndexOf('.'))) @@ -370,18 +371,19 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { this._isWorkspaceShellAllowed, getSystemShell(platform.platform), process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'), - process.env.windir + process.env.windir, + configurationResolverService ); } - private _getDefaultShellArgs(configProvider: ExtHostConfigProvider): string[] | string | undefined { + private _getDefaultShellArgs(configProvider: ExtHostConfigProvider, configurationResolverService: IConfigurationResolverService): string[] { const fetchSetting = (key: string) => { const setting = configProvider .getConfiguration(key.substr(0, key.lastIndexOf('.'))) .inspect(key.substr(key.lastIndexOf('.') + 1)); return this._apiInspectConfigToPlain(setting); }; - return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed); + return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, configurationResolverService); } public async resolveTerminalRenderer(id: number): Promise { @@ -530,7 +532,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return env; } - public async $createProcess(id: number, shellLaunchConfigDto: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise { + public async $createProcess(id: number, shellLaunchConfigDto: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean, configurationResolverService: IConfigurationResolverService): Promise { const shellLaunchConfig: IShellLaunchConfig = { name: shellLaunchConfigDto.name, executable: shellLaunchConfigDto.executable, @@ -543,8 +545,8 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux'); const configProvider = await this._extHostConfiguration.getConfigProvider(); if (!shellLaunchConfig.executable) { - shellLaunchConfig.executable = this.getDefaultShell(configProvider); - shellLaunchConfig.args = this._getDefaultShellArgs(configProvider); + shellLaunchConfig.executable = this.getDefaultShell(configProvider, configurationResolverService); + shellLaunchConfig.args = this._getDefaultShellArgs(configProvider, configurationResolverService); } // Get the initial cwd @@ -631,11 +633,11 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return detectAvailableShells(); } - public async $requestDefaultShellAndArgs(): Promise { + public async $requestDefaultShellAndArgs(configurationResolverService: IConfigurationResolverService): Promise { const configProvider = await this._extHostConfiguration.getConfigProvider(); return Promise.resolve({ - shell: this.getDefaultShell(configProvider), - args: this._getDefaultShellArgs(configProvider) + shell: this.getDefaultShell(configProvider, configurationResolverService), + args: this._getDefaultShellArgs(configProvider, configurationResolverService) }); } diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 87d6820117c6e..31dfd621a7a58 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -773,7 +773,7 @@ export class TerminalTaskSystem implements ITaskSystem { let terminalName = this.createTerminalName(task); let originalCommand = task.command.name; if (isShellCommand) { - const defaultConfig = await this.terminalInstanceService.getDefaultShellAndArgs(platform); + const defaultConfig = await this.terminalInstanceService.getDefaultShellAndArgs(undefined, platform); shellLaunchConfig = { name: terminalName, executable: defaultConfig.shell, args: defaultConfig.args, waitOnExit }; let shellSpecified: boolean = false; let shellOptions: ShellConfiguration | undefined = task.command.options && task.command.options.shell; diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index c9e3bdb74a36f..3a69bd04cd00c 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -10,6 +10,7 @@ import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITermina import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IProcessEnvironment, Platform } from 'vs/base/common/platform'; import { Event } from 'vs/base/common/event'; +import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; export const ITerminalInstanceService = createDecorator('terminalInstanceService'); @@ -30,7 +31,7 @@ export interface ITerminalInstanceService { createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper; createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess; - getDefaultShellAndArgs(platformOverride?: Platform): Promise<{ shell: string, args: string[] | string | undefined }>; + getDefaultShellAndArgs(configurationResolverService?: IConfigurationResolverService, platformOverride?: Platform): Promise<{ shell: string, args: string[] | string | undefined }>; getMainProcessParentEnv(): Promise; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index 5bbb061270950..d86233569e649 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -185,7 +185,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { isScreenReaderModeEnabled: boolean ): Promise { if (!shellLaunchConfig.executable) { - const defaultConfig = await this._terminalInstanceService.getDefaultShellAndArgs(); + const defaultConfig = await this._terminalInstanceService.getDefaultShellAndArgs(this._configurationResolverService); shellLaunchConfig.executable = defaultConfig.shell; shellLaunchConfig.args = defaultConfig.args; } diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index 011ec3be6ee51..bdafb5125bb3e 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -169,7 +169,8 @@ export function getDefaultShell( defaultShell: string, isWoW64: boolean, windir: string | undefined, - platformOverride: platform.Platform = platform.platform + configurationResolverService?: IConfigurationResolverService, + platformOverride: platform.Platform = platform.platform, ): string { const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux'; const shellConfigValue = fetchSetting(`terminal.integrated.shell.${platformKey}`); @@ -190,17 +191,29 @@ export function getDefaultShell( executable = executable.replace(/\//g, '\\'); } + if (configurationResolverService) { + executable = configurationResolverService.resolve(undefined, executable); + } + return executable; } export function getDefaultShellArgs( fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined }, isWorkspaceShellAllowed: boolean, - platformOverride: platform.Platform = platform.platform + configurationResolverService?: IConfigurationResolverService, + platformOverride: platform.Platform = platform.platform, ): string[] { const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux'; const shellArgsConfigValue = fetchSetting(`terminal.integrated.shellArgs.${platformKey}`); - const args = (isWorkspaceShellAllowed ? shellArgsConfigValue.value : shellArgsConfigValue.user) || shellArgsConfigValue.default; + let args = (isWorkspaceShellAllowed ? shellArgsConfigValue.value : shellArgsConfigValue.user) || shellArgsConfigValue.default; + if (configurationResolverService) { + const resolvedArgs: string[] = []; + for (const arg of args) { + resolvedArgs.push(configurationResolverService.resolve(undefined, arg)); + } + args = resolvedArgs; + } return args; } @@ -235,17 +248,6 @@ export function createTerminalEnvironment( if (shellLaunchConfig.env) { resolveConfigurationVariables(configurationResolverService, shellLaunchConfig.env, lastActiveWorkspace); } - if (shellLaunchConfig.args) { - if (Array.isArray(shellLaunchConfig.args)) { - const resolvedArgs: string[] = []; - for (const arg of shellLaunchConfig.args) { - resolvedArgs.push(configurationResolverService.resolve(undefined, arg)); - } - shellLaunchConfig.args = resolvedArgs; - } else { - shellLaunchConfig.args = configurationResolverService.resolve(undefined, shellLaunchConfig.args); - } - } } // Merge config (settings) and ShellLaunchConfig environments diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts index 94b5a713671b9..ac9b124ef784a 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts @@ -17,6 +17,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { getDefaultShell, getDefaultShellArgs } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage'; import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; +import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; let Terminal: typeof XTermTerminal; let WebLinksAddon: typeof XTermWebLinksAddon; @@ -65,7 +66,7 @@ export class TerminalInstanceService implements ITerminalInstanceService { return this._storageService.getBoolean(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, StorageScope.WORKSPACE, false); } - public getDefaultShellAndArgs(platformOverride: Platform = platform): Promise<{ shell: string, args: string[] | undefined }> { + public getDefaultShellAndArgs(configurationResolverService: IConfigurationResolverService, platformOverride: Platform = platform): Promise<{ shell: string, args: string[] | undefined }> { const isWorkspaceShellAllowed = this._isWorkspaceShellAllowed(); const shell = getDefaultShell( (key) => this._configurationService.inspect(key), @@ -73,11 +74,13 @@ export class TerminalInstanceService implements ITerminalInstanceService { getSystemShell(platformOverride), process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'), process.env.windir, + configurationResolverService, platformOverride ); const args = getDefaultShellArgs( (key) => this._configurationService.inspect(key), isWorkspaceShellAllowed, + configurationResolverService, platformOverride ); return Promise.resolve({ shell, args }); From 88b4244c2bd4fa84a16bf55b9137a94f74de0453 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Tue, 9 Jul 2019 11:07:38 -0700 Subject: [PATCH 03/19] Fix routing of resolver in extHost --- .../api/browser/mainThreadTerminalService.ts | 14 +++++------ .../workbench/api/common/extHost.protocol.ts | 5 ++-- .../api/node/extHostTerminalService.ts | 23 ++++++++++--------- .../tasks/browser/terminalTaskSystem.ts | 2 +- .../contrib/terminal/browser/terminal.ts | 2 +- .../browser/terminalProcessManager.ts | 2 +- .../terminal/common/terminalEnvironment.ts | 4 ++-- .../terminalInstanceService.ts | 9 ++++---- 8 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index becfbf686547d..d85bce215fb63 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -11,7 +11,6 @@ import { URI } from 'vs/base/common/uri'; import { StopWatch } from 'vs/base/common/stopwatch'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; -import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; @extHostNamedCustomer(MainContext.MainThreadTerminalService) export class MainThreadTerminalService implements MainThreadTerminalServiceShape { @@ -29,7 +28,6 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape @ITerminalService private readonly _terminalService: ITerminalService, @ITerminalInstanceService readonly terminalInstanceService: ITerminalInstanceService, @IRemoteAgentService readonly _remoteAgentService: IRemoteAgentService, - @IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTerminalService); this._remoteAuthority = extHostContext.remoteAuthority; @@ -49,7 +47,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._toDispose.add(_terminalService.onInstanceProcessIdReady(instance => this._onTerminalProcessIdReady(instance))); this._toDispose.add(_terminalService.onInstanceDimensionsChanged(instance => this._onInstanceDimensionsChanged(instance))); this._toDispose.add(_terminalService.onInstanceMaximumDimensionsChanged(instance => this._onInstanceMaximumDimensionsChanged(instance))); - this._toDispose.add(_terminalService.onInstanceRequestExtHostProcess(request => this._onTerminalRequestExtHostProcess(request, this._configurationResolverService))); + this._toDispose.add(_terminalService.onInstanceRequestExtHostProcess(request => this._onTerminalRequestExtHostProcess(request))); this._toDispose.add(_terminalService.onInstanceRequestVirtualProcess(proxy => this._onTerminalRequestVirtualProcess(proxy))); this._toDispose.add(_terminalService.onActiveInstanceChanged(instance => this._onActiveTerminalChanged(instance ? instance.id : null))); this._toDispose.add(_terminalService.onInstanceTitleChanged(instance => this._onTitleChanged(instance.id, instance.title))); @@ -58,7 +56,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape // ITerminalInstanceService listeners if (terminalInstanceService.onRequestDefaultShellAndArgs) { - this._toDispose.add(terminalInstanceService.onRequestDefaultShellAndArgs(e => this._onRequestDefaultShellAndArgs(e, this._configurationResolverService))); + this._toDispose.add(terminalInstanceService.onRequestDefaultShellAndArgs(e => this._onRequestDefaultShellAndArgs(e))); } // Set initial ext host state @@ -240,7 +238,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._proxy.$acceptTerminalMaximumDimensions(instance.id, instance.maxCols, instance.maxRows); } - private _onTerminalRequestExtHostProcess(request: ITerminalProcessExtHostRequest, configurationResolverService: IConfigurationResolverService): void { + private _onTerminalRequestExtHostProcess(request: ITerminalProcessExtHostRequest): void { // Only allow processes on remote ext hosts if (!this._remoteAuthority) { return; @@ -260,7 +258,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape cwd: request.shellLaunchConfig.cwd, env: request.shellLaunchConfig.env }; - this._proxy.$createProcess(request.proxy.terminalId, shellLaunchConfigDto, request.activeWorkspaceRootUri, request.cols, request.rows, request.isWorkspaceShellAllowed, configurationResolverService); + this._proxy.$createProcess(request.proxy.terminalId, shellLaunchConfigDto, request.activeWorkspaceRootUri, request.cols, request.rows, request.isWorkspaceShellAllowed); request.proxy.onInput(data => this._proxy.$acceptProcessInput(request.proxy.terminalId, data)); request.proxy.onResize(dimensions => this._proxy.$acceptProcessResize(request.proxy.terminalId, dimensions.cols, dimensions.rows)); request.proxy.onShutdown(immediate => this._proxy.$acceptProcessShutdown(request.proxy.terminalId, immediate)); @@ -343,9 +341,9 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } } - private _onRequestDefaultShellAndArgs(request: IDefaultShellAndArgsRequest, configurationResolverService: IConfigurationResolverService): void { + private _onRequestDefaultShellAndArgs(request: IDefaultShellAndArgsRequest): void { if (this._isPrimaryExtHost()) { - this._proxy.$requestDefaultShellAndArgs(configurationResolverService).then(e => request(e.shell, e.args)); + this._proxy.$requestDefaultShellAndArgs().then(e => request(e.shell, e.args)); } } } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index ab73ef8a756ad..1f2802ea39064 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -47,7 +47,6 @@ import { IRelativePattern } from 'vs/base/common/glob'; import { IRemoteConsoleLog } from 'vs/base/common/console'; import { VSBuffer } from 'vs/base/common/buffer'; import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; -import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; export interface IEnvironment { isExtensionDevelopmentDebug: boolean; @@ -1162,7 +1161,7 @@ export interface ExtHostTerminalServiceShape { $acceptTerminalTitleChange(id: number, name: string): void; $acceptTerminalDimensions(id: number, cols: number, rows: number): void; $acceptTerminalMaximumDimensions(id: number, cols: number, rows: number): void; - $createProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, activeWorkspaceRootUri: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean, configurationResolverService: IConfigurationResolverService): void; + $createProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, activeWorkspaceRootUri: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void; $acceptProcessInput(id: number, data: string): void; $acceptProcessResize(id: number, cols: number, rows: number): void; $acceptProcessShutdown(id: number, immediate: boolean): void; @@ -1171,7 +1170,7 @@ export interface ExtHostTerminalServiceShape { $acceptProcessRequestLatency(id: number): number; $acceptWorkspacePermissionsChanged(isAllowed: boolean): void; $requestAvailableShells(): Promise; - $requestDefaultShellAndArgs(configurationResolverService: IConfigurationResolverService): Promise; + $requestDefaultShellAndArgs(): Promise; } export interface ExtHostSCMShape { diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 5e249af32f71d..beda340b17b3d 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -23,7 +23,6 @@ import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocum import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal'; import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; const RENDERER_NO_PROCESS_ID = -1; @@ -359,7 +358,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return renderer; } - public getDefaultShell(configProvider: ExtHostConfigProvider, configurationResolverService?: IConfigurationResolverService): string { + public getDefaultShell(configProvider: ExtHostConfigProvider, configurationResolverService: ExtHostVariableResolverService | undefined): string { const fetchSetting = (key: string) => { const setting = configProvider .getConfiguration(key.substr(0, key.lastIndexOf('.'))) @@ -376,7 +375,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { ); } - private _getDefaultShellArgs(configProvider: ExtHostConfigProvider, configurationResolverService: IConfigurationResolverService): string[] { + private _getDefaultShellArgs(configProvider: ExtHostConfigProvider, configurationResolverService: ExtHostVariableResolverService | undefined): string[] { const fetchSetting = (key: string) => { const setting = configProvider .getConfiguration(key.substr(0, key.lastIndexOf('.'))) @@ -532,7 +531,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return env; } - public async $createProcess(id: number, shellLaunchConfigDto: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean, configurationResolverService: IConfigurationResolverService): Promise { + public async $createProcess(id: number, shellLaunchConfigDto: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise { const shellLaunchConfig: IShellLaunchConfig = { name: shellLaunchConfigDto.name, executable: shellLaunchConfigDto.executable, @@ -544,9 +543,11 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { // Merge in shell and args from settings const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux'); const configProvider = await this._extHostConfiguration.getConfigProvider(); + const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); + const variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; if (!shellLaunchConfig.executable) { - shellLaunchConfig.executable = this.getDefaultShell(configProvider, configurationResolverService); - shellLaunchConfig.args = this._getDefaultShellArgs(configProvider, configurationResolverService); + shellLaunchConfig.executable = this.getDefaultShell(configProvider, variableResolver); + shellLaunchConfig.args = this._getDefaultShellArgs(configProvider, variableResolver); } // Get the initial cwd @@ -565,8 +566,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { } } as IWorkspaceFolder : null; const envFromConfig = this._apiInspectConfigToPlain(configProvider.getConfiguration('terminal.integrated').inspect(`env.${platformKey}`)); - const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); - const variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; const baseEnv = terminalConfig.get('inheritEnv', true) ? process.env as platform.IProcessEnvironment : await this._getNonInheritedEnv(); const env = terminalEnvironment.createTerminalEnvironment( shellLaunchConfig, @@ -633,11 +632,13 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return detectAvailableShells(); } - public async $requestDefaultShellAndArgs(configurationResolverService: IConfigurationResolverService): Promise { + public async $requestDefaultShellAndArgs(): Promise { const configProvider = await this._extHostConfiguration.getConfigProvider(); + const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); + const variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; return Promise.resolve({ - shell: this.getDefaultShell(configProvider, configurationResolverService), - args: this._getDefaultShellArgs(configProvider, configurationResolverService) + shell: this.getDefaultShell(configProvider, variableResolver), + args: this._getDefaultShellArgs(configProvider, variableResolver) }); } diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 31dfd621a7a58..87d6820117c6e 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -773,7 +773,7 @@ export class TerminalTaskSystem implements ITaskSystem { let terminalName = this.createTerminalName(task); let originalCommand = task.command.name; if (isShellCommand) { - const defaultConfig = await this.terminalInstanceService.getDefaultShellAndArgs(undefined, platform); + const defaultConfig = await this.terminalInstanceService.getDefaultShellAndArgs(platform); shellLaunchConfig = { name: terminalName, executable: defaultConfig.shell, args: defaultConfig.args, waitOnExit }; let shellSpecified: boolean = false; let shellOptions: ShellConfiguration | undefined = task.command.options && task.command.options.shell; diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 3a69bd04cd00c..b59e7cddcf175 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -31,7 +31,7 @@ export interface ITerminalInstanceService { createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper; createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess; - getDefaultShellAndArgs(configurationResolverService?: IConfigurationResolverService, platformOverride?: Platform): Promise<{ shell: string, args: string[] | string | undefined }>; + getDefaultShellAndArgs(platformOverride?: Platform): Promise<{ shell: string, args: string[] | string | undefined }>; getMainProcessParentEnv(): Promise; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index d86233569e649..5bbb061270950 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -185,7 +185,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { isScreenReaderModeEnabled: boolean ): Promise { if (!shellLaunchConfig.executable) { - const defaultConfig = await this._terminalInstanceService.getDefaultShellAndArgs(this._configurationResolverService); + const defaultConfig = await this._terminalInstanceService.getDefaultShellAndArgs(); shellLaunchConfig.executable = defaultConfig.shell; shellLaunchConfig.args = defaultConfig.args; } diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index bdafb5125bb3e..21a78bcb250e1 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -169,7 +169,7 @@ export function getDefaultShell( defaultShell: string, isWoW64: boolean, windir: string | undefined, - configurationResolverService?: IConfigurationResolverService, + configurationResolverService: IConfigurationResolverService | undefined, platformOverride: platform.Platform = platform.platform, ): string { const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux'; @@ -201,7 +201,7 @@ export function getDefaultShell( export function getDefaultShellArgs( fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined }, isWorkspaceShellAllowed: boolean, - configurationResolverService?: IConfigurationResolverService, + configurationResolverService: IConfigurationResolverService | undefined, platformOverride: platform.Platform = platform.platform, ): string[] { const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux'; diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts index ac9b124ef784a..85b694b682db3 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts @@ -29,7 +29,8 @@ export class TerminalInstanceService implements ITerminalInstanceService { constructor( @IInstantiationService private readonly _instantiationService: IInstantiationService, @IConfigurationService private readonly _configurationService: IConfigurationService, - @IStorageService private readonly _storageService: IStorageService + @IStorageService private readonly _storageService: IStorageService, + @IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService ) { } @@ -66,7 +67,7 @@ export class TerminalInstanceService implements ITerminalInstanceService { return this._storageService.getBoolean(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, StorageScope.WORKSPACE, false); } - public getDefaultShellAndArgs(configurationResolverService: IConfigurationResolverService, platformOverride: Platform = platform): Promise<{ shell: string, args: string[] | undefined }> { + public getDefaultShellAndArgs(platformOverride: Platform = platform): Promise<{ shell: string, args: string[] | undefined }> { const isWorkspaceShellAllowed = this._isWorkspaceShellAllowed(); const shell = getDefaultShell( (key) => this._configurationService.inspect(key), @@ -74,13 +75,13 @@ export class TerminalInstanceService implements ITerminalInstanceService { getSystemShell(platformOverride), process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'), process.env.windir, - configurationResolverService, + this._configurationResolverService, platformOverride ); const args = getDefaultShellArgs( (key) => this._configurationService.inspect(key), isWorkspaceShellAllowed, - configurationResolverService, + this._configurationResolverService, platformOverride ); return Promise.resolve({ shell, args }); From 2a9f9dc9b0224edfbbd8062d70440361f46888cb Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Tue, 9 Jul 2019 11:10:04 -0700 Subject: [PATCH 04/19] Remove unnecessary comma --- src/vs/workbench/api/browser/mainThreadTerminalService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index d85bce215fb63..7883f70b7b651 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -27,7 +27,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape extHostContext: IExtHostContext, @ITerminalService private readonly _terminalService: ITerminalService, @ITerminalInstanceService readonly terminalInstanceService: ITerminalInstanceService, - @IRemoteAgentService readonly _remoteAgentService: IRemoteAgentService, + @IRemoteAgentService readonly _remoteAgentService: IRemoteAgentService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTerminalService); this._remoteAuthority = extHostContext.remoteAuthority; From 52b90508b1edc90b57390f53f29952d8a42cb9a3 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Tue, 9 Jul 2019 11:16:22 -0700 Subject: [PATCH 05/19] Compilation errors --- src/vs/workbench/contrib/terminal/browser/terminal.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index b59e7cddcf175..c9e3bdb74a36f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -10,7 +10,6 @@ import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITermina import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IProcessEnvironment, Platform } from 'vs/base/common/platform'; import { Event } from 'vs/base/common/event'; -import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; export const ITerminalInstanceService = createDecorator('terminalInstanceService'); From c6b1b4203e2c9a593a34f8fddf01c10be6ab01c2 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Tue, 9 Jul 2019 11:32:02 -0700 Subject: [PATCH 06/19] some async stuff --- src/vs/workbench/api/node/extHostTerminalService.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index beda340b17b3d..e6982730de763 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -375,14 +375,17 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { ); } - private _getDefaultShellArgs(configProvider: ExtHostConfigProvider, configurationResolverService: ExtHostVariableResolverService | undefined): string[] { + private async _getDefaultShellArgs(configProvider: ExtHostConfigProvider): Promise { const fetchSetting = (key: string) => { const setting = configProvider .getConfiguration(key.substr(0, key.lastIndexOf('.'))) .inspect(key.substr(key.lastIndexOf('.') + 1)); return this._apiInspectConfigToPlain(setting); }; - return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, configurationResolverService); + const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); + const variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; + + return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, variableResolver); } public async resolveTerminalRenderer(id: number): Promise { @@ -547,7 +550,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { const variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; if (!shellLaunchConfig.executable) { shellLaunchConfig.executable = this.getDefaultShell(configProvider, variableResolver); - shellLaunchConfig.args = this._getDefaultShellArgs(configProvider, variableResolver); + shellLaunchConfig.args = await this._getDefaultShellArgs(configProvider); } // Get the initial cwd @@ -638,7 +641,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { const variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; return Promise.resolve({ shell: this.getDefaultShell(configProvider, variableResolver), - args: this._getDefaultShellArgs(configProvider, variableResolver) + args: await this._getDefaultShellArgs(configProvider) }); } From 1a0e227a65d24dd17e4dee14bdf12247bb9c1010 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Tue, 9 Jul 2019 11:33:10 -0700 Subject: [PATCH 07/19] Undo changes --- src/vs/workbench/api/node/extHostTerminalService.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index e6982730de763..05a5197e1a2f5 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -375,17 +375,15 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { ); } - private async _getDefaultShellArgs(configProvider: ExtHostConfigProvider): Promise { + private _getDefaultShellArgs(configProvider: ExtHostConfigProvider, configurationResolverService: ExtHostVariableResolverService | undefined): string[] { const fetchSetting = (key: string) => { const setting = configProvider .getConfiguration(key.substr(0, key.lastIndexOf('.'))) .inspect(key.substr(key.lastIndexOf('.') + 1)); return this._apiInspectConfigToPlain(setting); }; - const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); - const variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; - return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, variableResolver); + return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, configurationResolverService); } public async resolveTerminalRenderer(id: number): Promise { @@ -550,7 +548,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { const variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; if (!shellLaunchConfig.executable) { shellLaunchConfig.executable = this.getDefaultShell(configProvider, variableResolver); - shellLaunchConfig.args = await this._getDefaultShellArgs(configProvider); + shellLaunchConfig.args = this._getDefaultShellArgs(configProvider, variableResolver); } // Get the initial cwd @@ -641,7 +639,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { const variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; return Promise.resolve({ shell: this.getDefaultShell(configProvider, variableResolver), - args: await this._getDefaultShellArgs(configProvider) + args: this._getDefaultShellArgs(configProvider, variableResolver) }); } From 700885b9288b11340e27d9c7392bc86d14d6a715 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Wed, 10 Jul 2019 09:24:56 -0700 Subject: [PATCH 08/19] Variable resolver in constructor --- .../workbench/api/node/extHostTerminalService.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index d3220eb84641d..1f8275b58f31a 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -286,6 +286,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { private _terminalProcesses: { [id: number]: ITerminalChildProcess } = {}; private _terminalRenderers: ExtHostTerminalRenderer[] = []; private _getTerminalPromises: { [id: number]: Promise } = {}; + private _variableResolver: ExtHostVariableResolverService | undefined; // TODO: Pull this from main side private _isWorkspaceShellAllowed: boolean = false; @@ -310,6 +311,11 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { private _logService: ILogService, ) { this._proxy = mainContext.getProxy(MainContext.MainThreadTerminalService); + this._extHostConfiguration.getConfigProvider().then((configProvider) => { + this._extHostWorkspace.getWorkspaceFolders2().then((workspaceFolders) => { + this._variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; + }); + }); } public createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal { @@ -544,11 +550,9 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { // Merge in shell and args from settings const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux'); const configProvider = await this._extHostConfiguration.getConfigProvider(); - const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); - const variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; if (!shellLaunchConfig.executable) { - shellLaunchConfig.executable = this.getDefaultShell(configProvider, variableResolver); - shellLaunchConfig.args = this._getDefaultShellArgs(configProvider, variableResolver); + shellLaunchConfig.executable = this.getDefaultShell(configProvider, this._variableResolver); + shellLaunchConfig.args = this._getDefaultShellArgs(configProvider, this._variableResolver); } // Get the initial cwd @@ -572,7 +576,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { shellLaunchConfig, lastActiveWorkspace, envFromConfig, - variableResolver, + this._variableResolver, isWorkspaceShellAllowed, pkg.version, terminalConfig.get('setLocaleVariables', false), From bdd6563ad6cb44fd312ce8f427faa31b51438324 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Wed, 10 Jul 2019 09:41:08 -0700 Subject: [PATCH 09/19] Load resolver upon construction of extHostTerminalService --- src/vs/workbench/api/node/extHost.api.impl.ts | 2 +- .../api/node/extHostTerminalService.ts | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index d385a9d087a6a..018dec12b5b69 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -258,7 +258,7 @@ export function createApiFactory( return extHostClipboard; }, get shell() { - return extHostTerminalService.getDefaultShell(configProvider, undefined); + return extHostTerminalService.getDefaultShell(configProvider); }, openExternal(uri: URI) { return extHostWindow.openUri(uri, { allowTunneling: !!initData.remote.isRemote }); diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 1f8275b58f31a..10d91a1c87778 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -364,7 +364,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return renderer; } - public getDefaultShell(configProvider: ExtHostConfigProvider, configurationResolverService: ExtHostVariableResolverService | undefined): string { + public getDefaultShell(configProvider: ExtHostConfigProvider): string { const fetchSetting = (key: string) => { const setting = configProvider .getConfiguration(key.substr(0, key.lastIndexOf('.'))) @@ -377,11 +377,11 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { getSystemShell(platform.platform), process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'), process.env.windir, - configurationResolverService + this._variableResolver ); } - private _getDefaultShellArgs(configProvider: ExtHostConfigProvider, configurationResolverService: ExtHostVariableResolverService | undefined): string[] { + private _getDefaultShellArgs(configProvider: ExtHostConfigProvider): string[] { const fetchSetting = (key: string) => { const setting = configProvider .getConfiguration(key.substr(0, key.lastIndexOf('.'))) @@ -389,7 +389,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return this._apiInspectConfigToPlain(setting); }; - return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, configurationResolverService); + return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, this._variableResolver); } public async resolveTerminalRenderer(id: number): Promise { @@ -551,8 +551,8 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux'); const configProvider = await this._extHostConfiguration.getConfigProvider(); if (!shellLaunchConfig.executable) { - shellLaunchConfig.executable = this.getDefaultShell(configProvider, this._variableResolver); - shellLaunchConfig.args = this._getDefaultShellArgs(configProvider, this._variableResolver); + shellLaunchConfig.executable = this.getDefaultShell(configProvider); + shellLaunchConfig.args = this._getDefaultShellArgs(configProvider); } // Get the initial cwd @@ -639,11 +639,9 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { public async $requestDefaultShellAndArgs(): Promise { const configProvider = await this._extHostConfiguration.getConfigProvider(); - const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); - const variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; return Promise.resolve({ - shell: this.getDefaultShell(configProvider, variableResolver), - args: this._getDefaultShellArgs(configProvider, variableResolver) + shell: this.getDefaultShell(configProvider), + args: this._getDefaultShellArgs(configProvider) }); } From cefd4e88200fbccf678cfc5e590929bd78843abb Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Fri, 12 Jul 2019 11:12:02 -0700 Subject: [PATCH 10/19] Utilize last active workspace root --- .../workbench/api/node/extHostTerminalService.ts | 15 +++++++++++++-- .../terminal/common/terminalEnvironment.ts | 6 ++++-- .../electron-browser/terminalInstanceService.ts | 11 ++++++++++- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 10d91a1c87778..b798ea5a099f6 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -287,6 +287,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { private _terminalRenderers: ExtHostTerminalRenderer[] = []; private _getTerminalPromises: { [id: number]: Promise } = {}; private _variableResolver: ExtHostVariableResolverService | undefined; + private _lastActiveWorkspace: IWorkspaceFolder | undefined; // TODO: Pull this from main side private _isWorkspaceShellAllowed: boolean = false; @@ -308,9 +309,10 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { private _extHostConfiguration: ExtHostConfiguration, private _extHostWorkspace: ExtHostWorkspace, private _extHostDocumentsAndEditors: ExtHostDocumentsAndEditors, - private _logService: ILogService, + private _logService: ILogService ) { this._proxy = mainContext.getProxy(MainContext.MainThreadTerminalService); + this.registerListeners(); this._extHostConfiguration.getConfigProvider().then((configProvider) => { this._extHostWorkspace.getWorkspaceFolders2().then((workspaceFolders) => { this._variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; @@ -377,6 +379,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { getSystemShell(platform.platform), process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'), process.env.windir, + this._lastActiveWorkspace, this._variableResolver ); } @@ -389,7 +392,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return this._apiInspectConfigToPlain(setting); }; - return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, this._variableResolver); + return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, this._lastActiveWorkspace, this._variableResolver); } public async resolveTerminalRenderer(id: number): Promise { @@ -538,6 +541,14 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return env; } + private registerListeners() { + this._extHostDocumentsAndEditors.onDidChangeActiveTextEditor(e => { + if (e) { + this._lastActiveWorkspace = this._extHostWorkspace.getWorkspaceFolder(e.document.uri) as IWorkspaceFolder; + } + }); + } + public async $createProcess(id: number, shellLaunchConfigDto: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise { const shellLaunchConfig: IShellLaunchConfig = { name: shellLaunchConfigDto.name, diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index 21a78bcb250e1..cf4d85e3963b2 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -169,6 +169,7 @@ export function getDefaultShell( defaultShell: string, isWoW64: boolean, windir: string | undefined, + lastActiveWorkspace: IWorkspaceFolder | undefined, configurationResolverService: IConfigurationResolverService | undefined, platformOverride: platform.Platform = platform.platform, ): string { @@ -192,7 +193,7 @@ export function getDefaultShell( } if (configurationResolverService) { - executable = configurationResolverService.resolve(undefined, executable); + executable = configurationResolverService.resolve(lastActiveWorkspace, executable); } return executable; @@ -201,6 +202,7 @@ export function getDefaultShell( export function getDefaultShellArgs( fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined }, isWorkspaceShellAllowed: boolean, + lastActiveWorkspace: IWorkspaceFolder | undefined, configurationResolverService: IConfigurationResolverService | undefined, platformOverride: platform.Platform = platform.platform, ): string[] { @@ -210,7 +212,7 @@ export function getDefaultShellArgs( if (configurationResolverService) { const resolvedArgs: string[] = []; for (const arg of args) { - resolvedArgs.push(configurationResolverService.resolve(undefined, arg)); + resolvedArgs.push(configurationResolverService.resolve(lastActiveWorkspace, arg)); } args = resolvedArgs; } diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts index 85b694b682db3..615f2014f9283 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts @@ -18,6 +18,8 @@ import { getDefaultShell, getDefaultShellArgs } from 'vs/workbench/contrib/termi import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage'; import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; +import { IHistoryService } from 'vs/workbench/services/history/common/history'; +import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; let Terminal: typeof XTermTerminal; let WebLinksAddon: typeof XTermWebLinksAddon; @@ -30,7 +32,9 @@ export class TerminalInstanceService implements ITerminalInstanceService { @IInstantiationService private readonly _instantiationService: IInstantiationService, @IConfigurationService private readonly _configurationService: IConfigurationService, @IStorageService private readonly _storageService: IStorageService, - @IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService + @IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService, + @IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService, + @IHistoryService private readonly _historyService: IHistoryService ) { } @@ -69,18 +73,23 @@ export class TerminalInstanceService implements ITerminalInstanceService { public getDefaultShellAndArgs(platformOverride: Platform = platform): Promise<{ shell: string, args: string[] | undefined }> { const isWorkspaceShellAllowed = this._isWorkspaceShellAllowed(); + const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(); + let lastActiveWorkspace = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : undefined; + lastActiveWorkspace = lastActiveWorkspace === null ? undefined : lastActiveWorkspace; const shell = getDefaultShell( (key) => this._configurationService.inspect(key), isWorkspaceShellAllowed, getSystemShell(platformOverride), process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'), process.env.windir, + lastActiveWorkspace, this._configurationResolverService, platformOverride ); const args = getDefaultShellArgs( (key) => this._configurationService.inspect(key), isWorkspaceShellAllowed, + lastActiveWorkspace, this._configurationResolverService, platformOverride ); From bb02321b24ee66a8fcaee8af38df1758c818f711 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 15 Jul 2019 09:46:35 -0700 Subject: [PATCH 11/19] Reevaluate variableReoslver whenever the workspace gets new folder --- src/vs/workbench/api/node/extHostTerminalService.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index b798ea5a099f6..3757904364e9d 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -313,11 +313,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { ) { this._proxy = mainContext.getProxy(MainContext.MainThreadTerminalService); this.registerListeners(); - this._extHostConfiguration.getConfigProvider().then((configProvider) => { - this._extHostWorkspace.getWorkspaceFolders2().then((workspaceFolders) => { - this._variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; - }); - }); } public createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal { @@ -547,6 +542,12 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { this._lastActiveWorkspace = this._extHostWorkspace.getWorkspaceFolder(e.document.uri) as IWorkspaceFolder; } }); + this._extHostWorkspace.onDidChangeWorkspace(e => { + this._extHostConfiguration.getConfigProvider().then(async (configProvider) => { + const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); + this._variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; + }); + }); } public async $createProcess(id: number, shellLaunchConfigDto: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise { From 74b9779025c0d7b2633d39f109843dee0dce77de Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 15 Jul 2019 10:03:51 -0700 Subject: [PATCH 12/19] Fix types for string shellArgs --- src/vs/workbench/api/node/extHostTerminalService.ts | 2 +- .../contrib/terminal/common/terminalEnvironment.ts | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index f3918d6ffc058..f952828b99fbf 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -375,7 +375,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { ); } - private _getDefaultShellArgs(configProvider: ExtHostConfigProvider): string[] { + private _getDefaultShellArgs(configProvider: ExtHostConfigProvider): string[] | string { const fetchSetting = (key: string) => { const setting = configProvider .getConfiguration(key.substr(0, key.lastIndexOf('.'))) diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index cf4d85e3963b2..58b897d4aa6fe 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -205,10 +205,13 @@ export function getDefaultShellArgs( lastActiveWorkspace: IWorkspaceFolder | undefined, configurationResolverService: IConfigurationResolverService | undefined, platformOverride: platform.Platform = platform.platform, -): string[] { +): string | string[] { const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux'; const shellArgsConfigValue = fetchSetting(`terminal.integrated.shellArgs.${platformKey}`); - let args = (isWorkspaceShellAllowed ? shellArgsConfigValue.value : shellArgsConfigValue.user) || shellArgsConfigValue.default; + let args = ((isWorkspaceShellAllowed ? shellArgsConfigValue.value : shellArgsConfigValue.user) || shellArgsConfigValue.default); + if (typeof args === 'string' && platformOverride === platform.Platform.Windows) { + return configurationResolverService ? configurationResolverService.resolve(lastActiveWorkspace, args) : args; + } if (configurationResolverService) { const resolvedArgs: string[] = []; for (const arg of args) { From 3f41ded951daae7b729bb77b255e13eae0a45234 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 15 Jul 2019 10:07:14 -0700 Subject: [PATCH 13/19] Use async one level higher --- src/vs/workbench/api/node/extHostTerminalService.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index f952828b99fbf..681d78160120d 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -538,11 +538,10 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { this._lastActiveWorkspace = this._extHostWorkspace.getWorkspaceFolder(e.document.uri) as IWorkspaceFolder; } }); - this._extHostWorkspace.onDidChangeWorkspace(e => { - this._extHostConfiguration.getConfigProvider().then(async (configProvider) => { - const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); - this._variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; - }); + this._extHostWorkspace.onDidChangeWorkspace(async () => { + const configProvider = await this._extHostConfiguration.getConfigProvider(); + const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); + this._variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; }); } From 193098913676dd5916afde02349be3e0d636e265 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 15 Jul 2019 10:20:21 -0700 Subject: [PATCH 14/19] Fix compile issue --- .../terminal/electron-browser/terminalInstanceService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts index 615f2014f9283..e9b13c0d68fd4 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts @@ -71,7 +71,7 @@ export class TerminalInstanceService implements ITerminalInstanceService { return this._storageService.getBoolean(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, StorageScope.WORKSPACE, false); } - public getDefaultShellAndArgs(platformOverride: Platform = platform): Promise<{ shell: string, args: string[] | undefined }> { + public getDefaultShellAndArgs(platformOverride: Platform = platform): Promise<{ shell: string, args: string | string[] }> { const isWorkspaceShellAllowed = this._isWorkspaceShellAllowed(); const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(); let lastActiveWorkspace = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : undefined; From ea13e3aa785e8dd70e8cdb2de204e3dd5507ee6b Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 15 Jul 2019 11:02:31 -0700 Subject: [PATCH 15/19] Initialize resolver when exthost is created --- .../api/node/extHostTerminalService.ts | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 681d78160120d..0ba79f6f85fd7 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -312,6 +312,8 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { private _logService: ILogService ) { this._proxy = mainContext.getProxy(MainContext.MainThreadTerminalService); + this.updateLastActiveWorkspace(); + this.updateVariableResolver(); this.registerListeners(); } @@ -532,17 +534,22 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return env; } - private registerListeners() { - this._extHostDocumentsAndEditors.onDidChangeActiveTextEditor(e => { - if (e) { - this._lastActiveWorkspace = this._extHostWorkspace.getWorkspaceFolder(e.document.uri) as IWorkspaceFolder; - } - }); - this._extHostWorkspace.onDidChangeWorkspace(async () => { - const configProvider = await this._extHostConfiguration.getConfigProvider(); - const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); - this._variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; - }); + private registerListeners(): void { + this._extHostDocumentsAndEditors.onDidChangeActiveTextEditor(() => this.updateLastActiveWorkspace()); + this._extHostWorkspace.onDidChangeWorkspace(() => this.updateVariableResolver()); + } + + private updateLastActiveWorkspace(): void { + const activeEditor = this._extHostDocumentsAndEditors.activeEditor(); + if (activeEditor) { + this._lastActiveWorkspace = this._extHostWorkspace.getWorkspaceFolder(activeEditor.document.uri) as IWorkspaceFolder; + } + } + + private async updateVariableResolver(): Promise { + const configProvider = await this._extHostConfiguration.getConfigProvider(); + const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); + this._variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; } public async $createProcess(id: number, shellLaunchConfigDto: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise { From 5aef25dfd9f0dc81330d64396c80b73a7693eb33 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 15 Jul 2019 11:20:36 -0700 Subject: [PATCH 16/19] Fix ext host in remote case with no folder open --- src/vs/workbench/api/node/extHostTerminalService.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 0ba79f6f85fd7..ee953c08fd6df 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -549,7 +549,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { private async updateVariableResolver(): Promise { const configProvider = await this._extHostConfiguration.getConfigProvider(); const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); - this._variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined; + this._variableResolver = new ExtHostVariableResolverService(workspaceFolders || [], this._extHostDocumentsAndEditors, configProvider); } public async $createProcess(id: number, shellLaunchConfigDto: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise { @@ -568,6 +568,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { shellLaunchConfig.executable = this.getDefaultShell(configProvider); shellLaunchConfig.args = this._getDefaultShellArgs(configProvider); } + // TODO: Resolve terminal env, args, and executable if extension sets them as well // Get the initial cwd const terminalConfig = configProvider.getConfiguration('terminal.integrated'); From 8aa76e612bafc879d69b9ff1d07efbc428a58681 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 15 Jul 2019 11:30:08 -0700 Subject: [PATCH 17/19] Resolve args that an ecxctension passes in --- .../workbench/api/node/extHostTerminalService.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index ee953c08fd6df..0bb51aefe6c4f 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -567,6 +567,21 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { if (!shellLaunchConfig.executable) { shellLaunchConfig.executable = this.getDefaultShell(configProvider); shellLaunchConfig.args = this._getDefaultShellArgs(configProvider); + } else { + if (this._variableResolver) { + shellLaunchConfig.executable = this._variableResolver.resolve(this._lastActiveWorkspace, shellLaunchConfig.executable); + if (shellLaunchConfig.args) { + if (Array.isArray(shellLaunchConfig.args)) { + const resolvedArgs: string[] = []; + for (const arg of shellLaunchConfig.args) { + resolvedArgs.push(this._variableResolver.resolve(this._lastActiveWorkspace, arg)); + } + shellLaunchConfig.args = resolvedArgs; + } else { + shellLaunchConfig.args = this._variableResolver.resolve(this._lastActiveWorkspace, shellLaunchConfig.args); + } + } + } } // TODO: Resolve terminal env, args, and executable if extension sets them as well From e12aa666e3a186b7bc052292908f95648df6619f Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 15 Jul 2019 11:31:08 -0700 Subject: [PATCH 18/19] Remove TODO --- src/vs/workbench/api/node/extHostTerminalService.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 0bb51aefe6c4f..cc0794acf48fc 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -583,7 +583,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { } } } - // TODO: Resolve terminal env, args, and executable if extension sets them as well // Get the initial cwd const terminalConfig = configProvider.getConfiguration('terminal.integrated'); From 5343c5aafbf9914cc99f80736795c2fff4cf0d35 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 15 Jul 2019 14:27:35 -0700 Subject: [PATCH 19/19] Resolve extension arguments --- .../browser/terminalProcessManager.ts | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index 5bbb061270950..bfa9741748eb5 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -184,17 +184,29 @@ export class TerminalProcessManager implements ITerminalProcessManager { rows: number, isScreenReaderModeEnabled: boolean ): Promise { + const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file); + const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux'); + const lastActiveWorkspace = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : null; if (!shellLaunchConfig.executable) { const defaultConfig = await this._terminalInstanceService.getDefaultShellAndArgs(); shellLaunchConfig.executable = defaultConfig.shell; shellLaunchConfig.args = defaultConfig.args; + } else { + shellLaunchConfig.executable = this._configurationResolverService.resolve(lastActiveWorkspace === null ? undefined : lastActiveWorkspace, shellLaunchConfig.executable); + if (shellLaunchConfig.args) { + if (Array.isArray(shellLaunchConfig.args)) { + const resolvedArgs: string[] = []; + for (const arg of shellLaunchConfig.args) { + resolvedArgs.push(this._configurationResolverService.resolve(lastActiveWorkspace === null ? undefined : lastActiveWorkspace, arg)); + } + shellLaunchConfig.args = resolvedArgs; + } else { + shellLaunchConfig.args = this._configurationResolverService.resolve(lastActiveWorkspace === null ? undefined : lastActiveWorkspace, shellLaunchConfig.args); + } + } } - const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file); const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, this._environmentService.userHome, activeWorkspaceRootUri, this._configHelper.config.cwd); - - const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux'); - const lastActiveWorkspace = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : null; const envFromConfigValue = this._workspaceConfigurationService.inspect(`terminal.integrated.env.${platformKey}`); const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions(); const baseEnv = this._configHelper.config.inheritEnv ? process.env as platform.IProcessEnvironment : await this._terminalInstanceService.getMainProcessParentEnv();