Navigation Menu

Skip to content

Commit

Permalink
Implement creating a razzle terminal with approved API changes
Browse files Browse the repository at this point in the history
  • Loading branch information
GabeDeBacker committed Jan 11, 2019
1 parent 14ce518 commit e1d8493
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 25 deletions.
10 changes: 10 additions & 0 deletions src/vs/vscode.d.ts
Expand Up @@ -6843,6 +6843,16 @@ declare module 'vscode' {
* Object with environment variables that will be added to the VS Code process.
*/
env?: { [key: string]: string | null };

/**
* Whether the terminal process environment should be exactly as provided in
* `TerminalOptions.env`. When this is false (default), the environment will be based on the
* window's environment and also apply configured platform settings like
* `terminal.integrated.windows.env` on top.
* When this is true, the complete environment must be provided as nothing will be inherited from the process
* or any configuration.
*/
strictEnv?: boolean;
}

/**
Expand Down
Expand Up @@ -55,15 +55,16 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
// when the extension host process goes down ?
}

public $createTerminal(name?: string, shellPath?: string, shellArgs?: string[], cwd?: string, env?: { [key: string]: string }, waitOnExit?: boolean): Promise<{ id: number, name: string }> {
public $createTerminal(name?: string, shellPath?: string, shellArgs?: string[], cwd?: string, env?: { [key: string]: string }, waitOnExit?: boolean, strictEnv?: boolean): Promise<{ id: number, name: string }> {
const shellLaunchConfig: IShellLaunchConfig = {
name,
executable: shellPath,
args: shellArgs,
cwd,
waitOnExit,
ignoreConfigurationCwd: true,
env
env,
strictEnv
};
const terminal = this.terminalService.createTerminal(shellLaunchConfig);
return Promise.resolve({
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/api/node/extHost.protocol.ts
Expand Up @@ -344,7 +344,7 @@ export interface MainThreadProgressShape extends IDisposable {
}

export interface MainThreadTerminalServiceShape extends IDisposable {
$createTerminal(name?: string, shellPath?: string, shellArgs?: string[], cwd?: string | URI, env?: { [key: string]: string }, waitOnExit?: boolean): Promise<{ id: number, name: string }>;
$createTerminal(name?: string, shellPath?: string, shellArgs?: string[], cwd?: string | URI, env?: { [key: string]: string }, waitOnExit?: boolean, strictEnv?: boolean): Promise<{ id: number, name: string }>;
$createTerminalRenderer(name: string): Promise<number>;
$dispose(terminalId: number): void;
$hide(terminalId: number): void;
Expand Down
7 changes: 4 additions & 3 deletions src/vs/workbench/api/node/extHostTerminalService.ts
Expand Up @@ -104,9 +104,10 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi
shellArgs?: string[],
cwd?: string | URI,
env?: { [key: string]: string },
waitOnExit?: boolean
waitOnExit?: boolean,
strictEnv?: boolean
): void {
this._proxy.$createTerminal(this._name, shellPath, shellArgs, cwd, env, waitOnExit).then(terminal => {
this._proxy.$createTerminal(this._name, shellPath, shellArgs, cwd, env, waitOnExit, strictEnv).then(terminal => {
this._name = terminal.name;
this._runQueuedRequests(terminal.id);
});
Expand Down Expand Up @@ -269,7 +270,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {

public createTerminalFromOptions(options: vscode.TerminalOptions): vscode.Terminal {
const terminal = new ExtHostTerminal(this._proxy, options.name);
terminal.create(options.shellPath, options.shellArgs, options.cwd, options.env /*, options.waitOnExit*/);
terminal.create(options.shellPath, options.shellArgs, options.cwd, options.env, /*options.waitOnExit*/ undefined, options.strictEnv);
this._terminals.push(terminal);
return terminal;
}
Expand Down
8 changes: 8 additions & 0 deletions src/vs/workbench/parts/terminal/common/terminal.ts
Expand Up @@ -181,6 +181,14 @@ export interface IShellLaunchConfig {
* extensions full control over the terminal.
*/
isRendererOnly?: boolean;

/**
* Whether the terminal process environment should be exactly as provided in
* `TerminalOptions.env`. When this is false (default), the environment will be based on the
* window's environment and also apply configured platform settings like
* `terminal.integrated.windows.env` on top.
*/
strictEnv?: boolean;
}

export interface ITerminalService {
Expand Down
Expand Up @@ -111,26 +111,34 @@ export class TerminalProcessManager implements ITerminalProcessManager {
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file);
this.initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, activeWorkspaceRootUri, this._configHelper.config.cwd);

// Resolve env vars from config and shell
const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : null;
const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
const envFromConfig = terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, { ...this._configHelper.config.env[platformKey] }, lastActiveWorkspaceRoot);
const envFromShell = terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, { ...shellLaunchConfig.env }, lastActiveWorkspaceRoot);
shellLaunchConfig.env = envFromShell;

// Compell type system as process.env should not have any undefined entries
const env: platform.IProcessEnvironment = { ...process.env } as any;

// Merge process env with the env from config and from shellLaunchConfig
terminalEnvironment.mergeEnvironments(env, envFromConfig);
terminalEnvironment.mergeEnvironments(env, shellLaunchConfig.env);

// Sanitize the environment, removing any undesirable VS Code and Electron environment
// variables
terminalEnvironment.sanitizeEnvironment(env);

// Adding other env keys necessary to create the process
terminalEnvironment.addTerminalEnvironmentKeys(env, platform.locale, this._configHelper.config.setLocaleVariables);
let env: platform.IProcessEnvironment = {};

// When this is true, the caller must provide the complete environment as nothing will be inherited from the process
// or any configuration.
if (shellLaunchConfig.strictEnv) {
env = { ...shellLaunchConfig.env } as any;
} else {
// Merge process env with the env from config and from shellLaunchConfig
env = { ...process.env } as any;

// Resolve env vars from config and shell
const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : null;
const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
const envFromConfig = terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, { ...this._configHelper.config.env[platformKey] }, lastActiveWorkspaceRoot);
const envFromShell = terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, { ...shellLaunchConfig.env }, lastActiveWorkspaceRoot);
shellLaunchConfig.env = envFromShell;

terminalEnvironment.mergeEnvironments(env, envFromConfig);
terminalEnvironment.mergeEnvironments(env, shellLaunchConfig.env);

// Sanitize the environment, removing any undesirable VS Code and Electron environment
// variables
terminalEnvironment.sanitizeEnvironment(env);

// Adding other env keys necessary to create the process
terminalEnvironment.addTerminalEnvironmentKeys(env, platform.locale, this._configHelper.config.setLocaleVariables);
}

this._logService.debug(`Terminal process launching`, shellLaunchConfig, this.initialCwd, cols, rows, env);
this._process = new TerminalProcess(shellLaunchConfig, this.initialCwd, cols, rows, env, this._configHelper.config.windowsEnableConpty);
Expand Down

0 comments on commit e1d8493

Please sign in to comment.