Start of terminal virtual processes

This commit is contained in:
Daniel Imms 2019-07-01 12:27:15 -07:00
parent c61bf317af
commit 2205cb69ed
6 changed files with 85 additions and 28 deletions

View file

@ -1256,6 +1256,46 @@ declare module 'vscode' {
//#endregion
//#region Terminal virtual process
// export function createTerminal(options: TerminalOptions | TerminalVirtualProcessOptions): Terminal;
export interface TerminalVirtualProcessOptions {
// For a name property for TerminalVirtualProcessOptions.
// Note that this is mandatory here as there's no process/shell to grab the title from
name: string;
virtualProcess: TerminalVirtualProcess;
// Allows Windows or non-Windows local link handler to be used based on Live Share host OS
// os?: OperatingSystem;
// Allows ~ to be resolved in Live Share
// userHome?: string;
}
interface TerminalVirtualProcess {
// The ext should fire this when they want to write to the terminal
write: Event<string>;
// Lets the extension override the dimensions of the terminal
overrideDimensions?: Event<TerminalDimensions>;
// Lets the extension exit the process with an exit code, this was not in the TerminalRenderer
// API but it makes sense to include this as it's the main thing missing for a virtual process
// to truly act like a process
exit?: Event<number>;
// This will be called when the user types
onDidAcceptInput?(text: string): void;
// This is called fire when window.onDidChangeTerminalDimensions fires as CustomExecution need
// access to the "maximum" dimensions and don't want access to Terminal
onDidChangeDimensions?(dimensions: TerminalDimensions): void;
}
//#endregion
//#region Joh -> exclusive document filters
export interface DocumentFilter {

View file

@ -76,7 +76,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
// when the extension host process goes down ?
}
public $createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string, cwd?: string | UriComponents, env?: { [key: string]: string }, waitOnExit?: boolean, strictEnv?: boolean, hideFromUser?: boolean): Promise<{ id: number, name: string }> {
public $createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string, cwd?: string | UriComponents, env?: { [key: string]: string }, waitOnExit?: boolean, strictEnv?: boolean, hideFromUser?: boolean, isVirtualProcess?: boolean): Promise<{ id: number, name: string }> {
const shellLaunchConfig: IShellLaunchConfig = {
name,
executable: shellPath,

View file

@ -390,7 +390,7 @@ export interface MainThreadProgressShape extends IDisposable {
}
export interface MainThreadTerminalServiceShape extends IDisposable {
$createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string, cwd?: string | UriComponents, env?: { [key: string]: string | null }, waitOnExit?: boolean, strictEnv?: boolean, hideFromUser?: boolean): Promise<{ id: number, name: string }>;
$createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string, cwd?: string | UriComponents, env?: { [key: string]: string | null }, waitOnExit?: boolean, strictEnv?: boolean, hideFromUser?: boolean, isVirtualProcess?: boolean): Promise<{ id: number, name: string }>;
$createTerminalRenderer(name: string): Promise<number>;
$dispose(terminalId: number): void;
$hide(terminalId: number): void;

View file

@ -116,14 +116,19 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi
env?: { [key: string]: string | null },
waitOnExit?: boolean,
strictEnv?: boolean,
hideFromUser?: boolean
hideFromUser?: boolean,
isVirtualProcess?: boolean
): void {
this._proxy.$createTerminal(this._name, shellPath, shellArgs, cwd, env, waitOnExit, strictEnv, hideFromUser).then(terminal => {
this._proxy.$createTerminal(this._name, shellPath, shellArgs, cwd, env, waitOnExit, strictEnv, hideFromUser, isVirtualProcess).then(terminal => {
this._name = terminal.name;
this._runQueuedRequests(terminal.id);
});
}
public createVirtualProcess(): void {
this.create(undefined, undefined, undefined, undefined, undefined, undefined, undefined, true);
}
public get name(): string {
return this._name || '';
}
@ -313,7 +318,11 @@ 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*/ undefined, options.strictEnv, options.hideFromUser);
if ((<any>options).isVirtualProcess) {
terminal.createVirtualProcess();
} else {
terminal.create(options.shellPath, options.shellArgs, options.cwd, options.env, /*options.waitOnExit*/ undefined, options.strictEnv, options.hideFromUser);
}
this._terminals.push(terminal);
return terminal;
}

View file

@ -103,32 +103,37 @@ export class TerminalProcessManager implements ITerminalProcessManager {
rows: number,
isScreenReaderModeEnabled: boolean
): Promise<void> {
const forceExtHostProcess = (this._configHelper.config as any).extHostProcess;
if (shellLaunchConfig.cwd && typeof shellLaunchConfig.cwd === 'object') {
this.remoteAuthority = getRemoteAuthority(shellLaunchConfig.cwd);
if (shellLaunchConfig.isVirtualProcess) {
// TODO: Hook up proxy
this._process = this._instantiationService.createInstance(TerminalProcessExtHostProxy, this._terminalId, shellLaunchConfig, undefined, cols, rows, this._configHelper);
} else {
this.remoteAuthority = this._environmentService.configuration.remoteAuthority;
}
const hasRemoteAuthority = !!this.remoteAuthority;
let launchRemotely = hasRemoteAuthority || forceExtHostProcess;
this.userHome = this._environmentService.userHome;
this.os = platform.OS;
if (launchRemotely) {
if (hasRemoteAuthority) {
this._remoteAgentService.getEnvironment().then(env => {
if (!env) {
return;
}
this.userHome = env.userHome.path;
this.os = env.os;
});
const forceExtHostProcess = (this._configHelper.config as any).extHostProcess;
if (shellLaunchConfig.cwd && typeof shellLaunchConfig.cwd === 'object') {
this.remoteAuthority = getRemoteAuthority(shellLaunchConfig.cwd);
} else {
this.remoteAuthority = this._environmentService.configuration.remoteAuthority;
}
const hasRemoteAuthority = !!this.remoteAuthority;
let launchRemotely = hasRemoteAuthority || forceExtHostProcess;
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot();
this._process = this._instantiationService.createInstance(TerminalProcessExtHostProxy, this._terminalId, shellLaunchConfig, activeWorkspaceRootUri, cols, rows, this._configHelper);
} else {
this._process = await this._launchProcess(shellLaunchConfig, cols, rows, isScreenReaderModeEnabled);
this.userHome = this._environmentService.userHome;
this.os = platform.OS;
if (launchRemotely) {
if (hasRemoteAuthority) {
this._remoteAgentService.getEnvironment().then(env => {
if (!env) {
return;
}
this.userHome = env.userHome.path;
this.os = env.os;
});
}
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot();
this._process = this._instantiationService.createInstance(TerminalProcessExtHostProxy, this._terminalId, shellLaunchConfig, activeWorkspaceRootUri, cols, rows, this._configHelper);
} else {
this._process = await this._launchProcess(shellLaunchConfig, cols, rows, isScreenReaderModeEnabled);
}
}
this.processState = ProcessState.LAUNCHING;

View file

@ -186,9 +186,12 @@ export interface IShellLaunchConfig {
/**
* When true the terminal will be created with no process. This is primarily used to give
* extensions full control over the terminal.
* @deprecated use `isVirtualProcess`
*/
isRendererOnly?: boolean;
isVirtualProcess?: 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