diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index ccc90b2f958..1080c5e46e7 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -4979,6 +4979,10 @@ declare module 'vscode' { * Args for the custom shell executable, this does not work on Windows (see #8429) */ shellArgs?: string[]; + /** + * Object with environment variables that will be added to the VS Code process. + */ + env?: { [key: string]: string | null }; } /** diff --git a/src/vs/workbench/api/electron-browser/mainThreadTerminalService.ts b/src/vs/workbench/api/electron-browser/mainThreadTerminalService.ts index a0c4d0db90f..aade4a664e3 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadTerminalService.ts @@ -33,13 +33,14 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape // when the extension host process goes down ? } - public $createTerminal(name?: string, shellPath?: string, shellArgs?: string[], waitOnExit?: boolean): TPromise { + public $createTerminal(name?: string, shellPath?: string, shellArgs?: string[], env?: { [key: string]: string }, waitOnExit?: boolean): TPromise { const shellLaunchConfig: IShellLaunchConfig = { name, executable: shellPath, args: shellArgs, waitOnExit, - ignoreConfigurationCwd: true + ignoreConfigurationCwd: true, + env }; return TPromise.as(this.terminalService.createInstance(shellLaunchConfig).id); } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 2e14b41c060..9d95254ff6a 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -291,7 +291,7 @@ export interface MainThreadProgressShape extends IDisposable { } export interface MainThreadTerminalServiceShape extends IDisposable { - $createTerminal(name?: string, shellPath?: string, shellArgs?: string[], waitOnExit?: boolean): TPromise; + $createTerminal(name?: string, shellPath?: string, shellArgs?: string[], env?: { [key: string]: string }, waitOnExit?: boolean): TPromise; $dispose(terminalId: number): void; $hide(terminalId: number): void; $sendText(terminalId: number, text: string, addNewLine: boolean): void; diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index e42fc83d1f6..adcd7ddd9a1 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -24,6 +24,7 @@ export class ExtHostTerminal implements vscode.Terminal { name?: string, shellPath?: string, shellArgs?: string[], + env?: { [key: string]: string }, waitOnExit?: boolean ) { this._name = name; @@ -32,7 +33,7 @@ export class ExtHostTerminal implements vscode.Terminal { this._pidPromise = new TPromise(c => { this._pidPromiseComplete = c; }); - this._proxy.$createTerminal(name, shellPath, shellArgs, waitOnExit).then((id) => { + this._proxy.$createTerminal(name, shellPath, shellArgs, env, waitOnExit).then((id) => { this._id = id; this._queuedRequests.forEach((r) => { r.run(this._proxy, this._id); @@ -113,7 +114,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { } public createTerminalFromOptions(options: vscode.TerminalOptions): vscode.Terminal { - let terminal = new ExtHostTerminal(this._proxy, options.name, options.shellPath, options.shellArgs/*, options.waitOnExit*/); + let terminal = new ExtHostTerminal(this._proxy, options.name, options.shellPath, options.shellArgs, options.env/*, options.waitOnExit*/); this._terminals.push(terminal); return terminal; } diff --git a/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts b/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts index b3e4d73c599..bf9e700758e 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts @@ -552,14 +552,7 @@ export class TerminalTaskSystem extends EventEmitter implements ITaskSystem { shellLaunchConfig.cwd = options.cwd; } if (options.env) { - let env: IStringDictionary = Object.create(null); - Object.keys(process.env).forEach((key) => { - env[key] = process.env[key]; - }); - Object.keys(options.env).forEach((key) => { - env[key] = options.env[key]; - }); - shellLaunchConfig.env = env; + shellLaunchConfig.env = options.env; } let prefersSameTerminal = task.command.presentation.panel === PanelKind.Dedicated; let allowsSharedTerminal = task.command.presentation.panel === PanelKind.Shared; diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index 81e366ea283..07075759c0b 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -778,7 +778,18 @@ export class TerminalInstance implements ITerminalInstance { // TODO: This should be private/protected // TODO: locale should not be optional public static createTerminalEnv(parentEnv: IStringDictionary, shell: IShellLaunchConfig, cwd: string, locale?: string, cols?: number, rows?: number): IStringDictionary { - const env = shell.env ? shell.env : TerminalInstance._cloneEnv(parentEnv); + const env = TerminalInstance._cloneEnv(parentEnv); + if (shell.env) { + Object.keys(shell.env).forEach((key) => { + const value = shell.env[key]; + if (typeof value === 'string') { + env[key] = value; + } else { + delete env[key]; + } + }); + } + env['PTYPID'] = process.pid.toString(); env['PTYSHELL'] = shell.executable; env['TERM_PROGRAM'] = 'vscode';