未验证 提交 03d1686d 编写于 作者: D Daniel Imms 提交者: GitHub

Merge pull request #77961 from microsoft/tyriar/77160

Use pty naming instead of virtual process
......@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { window, Terminal, TerminalVirtualProcess, EventEmitter, TerminalDimensions, workspace, ConfigurationTarget } from 'vscode';
import { window, Terminal, Pseudoterminal, EventEmitter, TerminalDimensions, workspace, ConfigurationTarget } from 'vscode';
import { doesNotThrow, equal, ok } from 'assert';
suite('window namespace tests', () => {
......@@ -264,12 +264,12 @@ suite('window namespace tests', () => {
});
term.dispose();
});
const virtualProcess: TerminalVirtualProcess = {
const pty: Pseudoterminal = {
onDidWrite: new EventEmitter<string>().event,
start: () => {},
shutdown: () => {}
open: () => {},
close: () => {}
};
window.createTerminal({ name: 'c', virtualProcess });
window.createTerminal({ name: 'c', pty });
});
test('should fire Terminal.onData on write', (done) => {
......@@ -291,12 +291,12 @@ suite('window namespace tests', () => {
let startResolve: () => void;
const startPromise: Promise<void> = new Promise<void>(r => startResolve = r);
const writeEmitter = new EventEmitter<string>();
const virtualProcess: TerminalVirtualProcess = {
const pty: Pseudoterminal = {
onDidWrite: writeEmitter.event,
start: () => startResolve(),
shutdown: () => {}
open: () => startResolve(),
close: () => {}
};
const terminal = window.createTerminal({ name: 'foo', virtualProcess });
const terminal = window.createTerminal({ name: 'foo', pty });
});
test('should fire provide dimensions on start as the terminal has been shown', (done) => {
......@@ -304,9 +304,9 @@ suite('window namespace tests', () => {
equal(terminal, term);
reg1.dispose();
});
const virtualProcess: TerminalVirtualProcess = {
const pty: Pseudoterminal = {
onDidWrite: new EventEmitter<string>().event,
start: (dimensions) => {
open: (dimensions) => {
ok(dimensions!.columns > 0);
ok(dimensions!.rows > 0);
const reg3 = window.onDidCloseTerminal(() => {
......@@ -315,9 +315,9 @@ suite('window namespace tests', () => {
});
terminal.dispose();
},
shutdown: () => {}
close: () => {}
};
const terminal = window.createTerminal({ name: 'foo', virtualProcess });
const terminal = window.createTerminal({ name: 'foo', pty });
});
test('should respect dimension overrides', (done) => {
......@@ -340,13 +340,13 @@ suite('window namespace tests', () => {
});
const writeEmitter = new EventEmitter<string>();
const overrideDimensionsEmitter = new EventEmitter<TerminalDimensions>();
const virtualProcess: TerminalVirtualProcess = {
const pty: Pseudoterminal = {
onDidWrite: writeEmitter.event,
onDidOverrideDimensions: overrideDimensionsEmitter.event,
start: () => {},
shutdown: () => {}
open: () => {},
close: () => {}
};
const terminal = window.createTerminal({ name: 'foo', virtualProcess });
const terminal = window.createTerminal({ name: 'foo', pty });
});
});
});
......
......@@ -35,17 +35,18 @@ suite('workspace-namespace', () => {
customProp1: 'testing task one'
};
const writeEmitter = new vscode.EventEmitter<string>();
const execution = new vscode.CustomExecution2((): Thenable<vscode.TerminalVirtualProcess> => {
return Promise.resolve(<vscode.TerminalVirtualProcess>{
const execution = new vscode.CustomExecution2((): Thenable<vscode.Pseudoterminal> => {
const pty: vscode.Pseudoterminal = {
onDidWrite: writeEmitter.event,
start: () => {
open: () => {
writeEmitter.fire('testing\r\n');
},
shutdown: () => {
close: () => {
taskProvider.dispose();
done();
}
});
};
return Promise.resolve(pty);
});
const task = new vscode.Task2(kind, vscode.TaskScope.Workspace, taskName, taskType, execution);
result.push(task);
......
......@@ -816,7 +816,7 @@ declare module 'vscode' {
* [Terminal.sendText](#Terminal.sendText) is triggered that will fire the
* [TerminalRenderer.onDidAcceptInput](#TerminalRenderer.onDidAcceptInput) event.
*
* @deprecated Use [virtual processes](#TerminalVirtualProcess) instead.
* @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead.
*
* **Example:** Create a terminal renderer, show it and write hello world in red
* ```typescript
......@@ -828,7 +828,7 @@ declare module 'vscode' {
export interface TerminalRenderer {
/**
* The name of the terminal, this will appear in the terminal selector.
* @deprecated Use [virtual processes](#TerminalVirtualProcess) instead.
* @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead.
*/
name: string;
......@@ -837,7 +837,7 @@ declare module 'vscode' {
* a value smaller than the maximum value, if this is undefined the terminal will auto fit
* to the maximum value [maximumDimensions](TerminalRenderer.maximumDimensions).
*
* @deprecated Use [virtual processes](#TerminalVirtualProcess) instead.
* @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead.
*
* **Example:** Override the dimensions of a TerminalRenderer to 20 columns and 10 rows
* ```typescript
......@@ -855,14 +855,14 @@ declare module 'vscode' {
* Listen to [onDidChangeMaximumDimensions](TerminalRenderer.onDidChangeMaximumDimensions)
* to get notified when this value changes.
*
* @deprecated Use [virtual processes](#TerminalVirtualProcess) instead.
* @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead.
*/
readonly maximumDimensions: TerminalDimensions | undefined;
/**
* The corresponding [Terminal](#Terminal) for this TerminalRenderer.
*
* @deprecated Use [virtual processes](#TerminalVirtualProcess) instead.
* @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead.
*/
readonly terminal: Terminal;
......@@ -871,7 +871,7 @@ declare module 'vscode' {
* text to the underlying _process_, this will write the text to the terminal itself.
*
* @param text The text to write.
* @deprecated Use [virtual processes](#TerminalVirtualProcess) instead.
* @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead.
*
* **Example:** Write red text to the terminal
* ```typescript
......@@ -890,7 +890,7 @@ declare module 'vscode' {
* [Terminal.sendText](#Terminal.sendText). Keystrokes are converted into their
* corresponding VT sequence representation.
*
* @deprecated Use [virtual processes](#TerminalVirtualProcess) instead.
* @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead.
*
* **Example:** Simulate interaction with the terminal from an outside extension or a
* workbench command such as `workbench.action.terminal.runSelectedText`
......@@ -908,7 +908,7 @@ declare module 'vscode' {
* An event which fires when the [maximum dimensions](#TerminalRenderer.maximumDimensions) of
* the terminal renderer change.
*
* @deprecated Use [virtual processes](#TerminalVirtualProcess) instead.
* @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead.
*/
readonly onDidChangeMaximumDimensions: Event<TerminalDimensions>;
}
......@@ -918,60 +918,60 @@ declare module 'vscode' {
* Create a [TerminalRenderer](#TerminalRenderer).
*
* @param name The name of the terminal renderer, this shows up in the terminal selector.
* @deprecated Use [virtual processes](#TerminalVirtualProcess) instead.
* @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead.
*/
export function createTerminalRenderer(name: string): TerminalRenderer;
}
//#endregion
//#region Terminal extension pty
//#region Extension terminals
export namespace window {
/**
* Creates a [Terminal](#Terminal) where an extension acts as the process.
* Creates a [Terminal](#Terminal) where an extension controls the teerminal.
*
* @param options A [TerminalVirtualProcessOptions](#TerminalVirtualProcessOptions) object describing the
* characteristics of the new terminal.
* @param options An [ExtensionTerminalOptions](#ExtensionTerminalOptions) object describing
* the characteristics of the new terminal.
* @return A new Terminal.
*/
export function createTerminal(options: TerminalVirtualProcessOptions): Terminal;
export function createTerminal(options: ExtensionTerminalOptions): Terminal;
}
/**
* Value-object describing what options a virtual process terminal should use.
*/
export interface TerminalVirtualProcessOptions {
export interface ExtensionTerminalOptions {
/**
* A human-readable string which will be used to represent the terminal in the UI.
*/
name: string;
/**
* An implementation of [TerminalVirtualProcess](#TerminalVirtualProcess) that allows an
* extension to act as a terminal's backing process.
* An implementation of [Pseudoterminal](#Pseudoterminal) that allows an extension to
* control a terminal.
*/
virtualProcess: TerminalVirtualProcess;
pty: Pseudoterminal;
}
/**
* Defines the interface of a terminal virtual process, enabling extensions to act as a process
* in the terminal.
* Defines the interface of a terminal pty, enabling extensions to control a terminal.
*/
interface TerminalVirtualProcess {
interface Pseudoterminal {
/**
* An event that when fired will write data to the terminal. Unlike
* [Terminal.sendText](#Terminal.sendText) which sends text to the underlying _process_,
* this will write the text to the terminal itself.
* [Terminal.sendText](#Terminal.sendText) which sends text to the underlying _process_
* (the pty "slave"), this will write the text to the terminal itself (the pty "master").
*
* **Example:** Write red text to the terminal
* ```typescript
* const writeEmitter = new vscode.EventEmitter<string>();
* const virtualProcess: TerminalVirtualProcess = {
* onDidWrite: writeEmitter.event
* const pty: vscode.Pseudoterminal = {
* onDidWrite: writeEmitter.event,
* open: () => writeEmitter.fire('\x1b[31mHello world\x1b[0m'),
* close: () => {}
* };
* vscode.window.createTerminal({ name: 'My terminal', virtualProcess });
* writeEmitter.fire('\x1b[31mHello world\x1b[0m');
* vscode.window.createTerminal({ name: 'My terminal', pty });
* ```
*
* **Example:** Move the cursor to the 10th row and 20th column and write an asterisk
......@@ -985,71 +985,82 @@ declare module 'vscode' {
* An event that when fired allows overriding the [dimensions](#Terminal.dimensions) of the
* terminal. Note that when set the overridden dimensions will only take effect when they
* are lower than the actual dimensions of the terminal (ie. there will never be a scroll
* bar). Set to `undefined` for the terminal to go back to the regular dimensions.
* bar). Set to `undefined` for the terminal to go back to the regular dimensions (fit to
* the size of the panel).
*
* **Example:** Override the dimensions of a terminal to 20 columns and 10 rows
* ```typescript
* const dimensionsEmitter = new vscode.EventEmitter<string>();
* const virtualProcess: TerminalVirtualProcess = {
* const pty: vscode.Pseudoterminal = {
* onDidWrite: writeEmitter.event,
* onDidOverrideDimensions: dimensionsEmitter.event
* onDidOverrideDimensions: dimensionsEmitter.event,
* open: () => {
* dimensionsEmitter.fire({
* columns: 20,
* rows: 10
* });
* },
* close: () => {}
* };
* vscode.window.createTerminal({ name: 'My terminal', virtualProcess });
* dimensionsEmitter.fire({
* columns: 20,
* rows: 10
* });
* vscode.window.createTerminal({ name: 'My terminal', pty });
* ```
*/
onDidOverrideDimensions?: Event<TerminalDimensions | undefined>;
/**
* An event that when fired will exit the process with an exit code, this will behave the
* same for a virtual process as when a regular process exits with an exit code. Note that
* exit codes must be positive numbers, when negative the exit code will be forced to `1`.
* An event that when fired will signal that the pty is closed and dispose of the terminal.
*
* **Example:** Exit with an exit code of `0` if the y key is pressed, otherwise `1`.
* **Example:** Exit the terminal when "y" is pressed, otherwise show a notification.
* ```typescript
* const writeEmitter = new vscode.EventEmitter<string>();
* const exitEmitter = new vscode.EventEmitter<number>();
* const virtualProcess: TerminalVirtualProcess = {
* const closeEmitter = new vscode.EventEmitter<number>();
* const pty: vscode.Pseudoterminal = {
* onDidWrite: writeEmitter.event,
* input: data => exitEmitter.fire(data === 'y' ? 0 : 1)
* onDidClose: closeEmitter.event,
* open: () => writeEmitter.fire('Press y to exit successfully'),
* close: () => {}
* handleInput: {
* if (data !== 'y') {
* vscode.window.showInformationMessage('Something went wrong');
* }
* data => closeEmitter.fire();
* }
* };
* vscode.window.createTerminal({ name: 'Exit example', virtualProcess });
* writeEmitter.fire('Press y to exit successfully');
* vscode.window.createTerminal({ name: 'Exit example', pty });
*/
onDidExit?: Event<number>;
onDidClose?: Event<void>;
/**
* Implement to handle when the terminal is ready to start firing events.
* Implement to handle when the pty is open and ready to start firing events.
*
* @param initialDimensions The dimensions of the terminal, this will be undefined if the
* terminal panel has not been opened before this is called.
*/
start(initialDimensions: TerminalDimensions | undefined): void;
open(initialDimensions: TerminalDimensions | undefined): void;
/**
* Implement to handle when the terminal shuts down by an act of the user.
* Implement to handle when the terminal is closed by an act of the user.
*/
shutdown(): void;
close(): void;
/**
* Implement to handle keystrokes in the terminal or when an extension calls
* [Terminal.sendText](#Terminal.sendText). Keystrokes are converted into their
* corresponding VT sequence representation.
* Implement to handle incoming keystrokes in the terminal or when an extension calls
* [Terminal.sendText](#Terminal.sendText). `data` contains the keystrokes/text serialized into
* their corresponding VT sequence representation.
*
* @param data The sent data.
* @param data The incoming data.
*
* **Example:** Echo input in the terminal. The sequence for enter (`\r`) is translated to
* CRLF to go to a new line and move the cursor to the start of the line.
* ```typescript
* const writeEmitter = new vscode.EventEmitter<string>();
* const virtualProcess: TerminalVirtualProcess = {
* const pty: vscode.Pseudoterminal = {
* onDidWrite: writeEmitter.event,
* open: () => {},
* close: () => {},
* handleInput: data => writeEmitter.fire(data === '\r' ? '\r\n' : data)
* };
* vscode.window.createTerminal({ name: 'Local echo', virtualProcess });
* vscode.window.createTerminal({ name: 'Local echo', pty });
* ```
*/
handleInput?(data: string): void;
......@@ -1145,6 +1156,7 @@ declare module 'vscode' {
}
//#endregion
//#region CustomExecution
/**
* Class used to execute an extension callback as a task.
*/
......@@ -1168,16 +1180,17 @@ declare module 'vscode' {
*/
export class CustomExecution2 {
/**
* @param process The [TerminalVirtualProcess](#TerminalVirtualProcess) to be used by the task to display output.
* @param process The [Pseudotrminal](#Pseudoterminal) to be used by the task to display output.
* @param callback The callback that will be called when the task is started by a user.
*/
constructor(callback: (thisArg?: any) => Thenable<TerminalVirtualProcess>);
constructor(callback: (thisArg?: any) => Thenable<Pseudoterminal>);
/**
* The callback used to execute the task. Cancellation should be handled using the shutdown method of [TerminalVirtualProcess](#TerminalVirtualProcess).
* When the task is complete, onDidExit should be fired on the TerminalVirtualProcess with the exit code with '0' for success and a non-zero value for failure.
* The callback used to execute the task. Cancellation should be handled using
* [Pseudoterminal.close](#Pseudoterminal.close). When the task is complete fire
* [Pseudoterminal.onDidClose](#Pseudoterminal.onDidClose).
*/
callback: (thisArg?: any) => Thenable<TerminalVirtualProcess>;
callback: (thisArg?: any) => Thenable<Pseudoterminal>;
}
/**
......@@ -1203,6 +1216,7 @@ declare module 'vscode' {
*/
execution2?: ProcessExecution | ShellExecution | CustomExecution | CustomExecution2;
}
//#endregion
//#region Tasks
export interface TaskPresentationOptions {
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, ITerminalDimensions, EXT_HOST_CREATION_DELAY, IAvailableShellsRequest, IDefaultShellAndArgsRequest, ITerminalVirtualProcessRequest } from 'vs/workbench/contrib/terminal/common/terminal';
import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalProcessExtHostProxy, ISpawnExtHostProcessRequest, ITerminalDimensions, EXT_HOST_CREATION_DELAY, IAvailableShellsRequest, IDefaultShellAndArgsRequest, IStartExtensionTerminalRequest } from 'vs/workbench/contrib/terminal/common/terminal';
import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, IExtHostContext, ShellLaunchConfigDto, TerminalLaunchConfig, ITerminalDimensionsDto } from 'vs/workbench/api/common/extHost.protocol';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { URI } from 'vs/base/common/uri';
......@@ -47,8 +47,8 @@ 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.onInstanceRequestVirtualProcess(e => this._onTerminalRequestVirtualProcess(e)));
this._toDispose.add(_terminalService.onInstanceRequestSpawnExtHostProcess(request => this._onRequestSpawnExtHostProcess(request)));
this._toDispose.add(_terminalService.onInstanceRequestStartExtensionTerminal(e => this._onRequestStartExtensionTerminal(e)));
this._toDispose.add(_terminalService.onActiveInstanceChanged(instance => this._onActiveTerminalChanged(instance ? instance.id : null)));
this._toDispose.add(_terminalService.onInstanceTitleChanged(instance => this._onTitleChanged(instance.id, instance.title)));
this._toDispose.add(_terminalService.configHelper.onWorkspacePermissionsChanged(isAllowed => this._onWorkspacePermissionsChanged(isAllowed)));
......@@ -90,7 +90,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
env: launchConfig.env,
strictEnv: launchConfig.strictEnv,
hideFromUser: launchConfig.hideFromUser,
isVirtualProcess: launchConfig.isVirtualProcess
isExtensionTerminal: launchConfig.isExtensionTerminal
};
const terminal = this._terminalService.createTerminal(shellLaunchConfig);
this._terminalProcesses.set(terminal.id, new Promise<ITerminalProcessExtHostProxy>(r => this._terminalProcessesReady.set(terminal.id, r)));
......@@ -240,7 +240,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
this._proxy.$acceptTerminalMaximumDimensions(instance.id, instance.maxCols, instance.maxRows);
}
private _onTerminalRequestExtHostProcess(request: ITerminalProcessExtHostRequest): void {
private _onRequestSpawnExtHostProcess(request: ISpawnExtHostProcessRequest): void {
// Only allow processes on remote ext hosts
if (!this._remoteAuthority) {
return;
......@@ -261,7 +261,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
cwd: request.shellLaunchConfig.cwd,
env: request.shellLaunchConfig.env
};
this._proxy.$createProcess(proxy.terminalId, shellLaunchConfigDto, request.activeWorkspaceRootUri, request.cols, request.rows, request.isWorkspaceShellAllowed);
this._proxy.$spawnExtHostProcess(proxy.terminalId, shellLaunchConfigDto, request.activeWorkspaceRootUri, request.cols, request.rows, request.isWorkspaceShellAllowed);
proxy.onInput(data => this._proxy.$acceptProcessInput(proxy.terminalId, data));
proxy.onResize(dimensions => this._proxy.$acceptProcessResize(proxy.terminalId, dimensions.cols, dimensions.rows));
proxy.onShutdown(immediate => this._proxy.$acceptProcessShutdown(proxy.terminalId, immediate));
......@@ -270,7 +270,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
proxy.onRequestLatency(() => this._onRequestLatency(proxy.terminalId));
}
private _onTerminalRequestVirtualProcess(request: ITerminalVirtualProcessRequest): void {
private _onRequestStartExtensionTerminal(request: IStartExtensionTerminalRequest): void {
const proxy = request.proxy;
const ready = this._terminalProcessesReady.get(proxy.terminalId);
if (!ready) {
......@@ -286,7 +286,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
columns: request.cols,
rows: request.rows
} : undefined;
this._proxy.$startVirtualProcess(proxy.terminalId, initialDimensions);
this._proxy.$startExtensionTerminal(proxy.terminalId, initialDimensions);
proxy.onInput(data => this._proxy.$acceptProcessInput(proxy.terminalId, data));
proxy.onShutdown(immediate => this._proxy.$acceptProcessShutdown(proxy.terminalId, immediate));
proxy.onRequestCwd(() => this._proxy.$acceptProcessRequestCwd(proxy.terminalId));
......
......@@ -390,7 +390,7 @@ export interface TerminalLaunchConfig {
waitOnExit?: boolean;
strictEnv?: boolean;
hideFromUser?: boolean;
isVirtualProcess?: boolean;
isExtensionTerminal?: boolean;
}
export interface MainThreadTerminalServiceShape extends IDisposable {
......@@ -1161,8 +1161,8 @@ 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;
$startVirtualProcess(id: number, initialDimensions: ITerminalDimensionsDto | undefined): void;
$spawnExtHostProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, activeWorkspaceRootUri: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void;
$startExtensionTerminal(id: number, initialDimensions: ITerminalDimensionsDto | undefined): void;
$acceptProcessInput(id: number, data: string): void;
$acceptProcessResize(id: number, cols: number, rows: number): void;
$acceptProcessShutdown(id: number, immediate: boolean): void;
......
......@@ -1774,19 +1774,19 @@ export class CustomExecution implements vscode.CustomExecution {
}
export class CustomExecution2 implements vscode.CustomExecution2 {
private _callback: () => Thenable<vscode.TerminalVirtualProcess>;
constructor(callback: () => Thenable<vscode.TerminalVirtualProcess>) {
private _callback: () => Thenable<vscode.Pseudoterminal>;
constructor(callback: () => Thenable<vscode.Pseudoterminal>) {
this._callback = callback;
}
public computeId(): string {
return 'customExecution' + generateUuid();
}
public set callback(value: () => Thenable<vscode.TerminalVirtualProcess>) {
public set callback(value: () => Thenable<vscode.Pseudoterminal>) {
this._callback = value;
}
public get callback(): (() => Thenable<vscode.TerminalVirtualProcess>) {
public get callback(): (() => Thenable<vscode.Pseudoterminal>) {
return this._callback;
}
}
......
......@@ -528,10 +528,10 @@ export function createApiFactory(
checkProposedApiEnabled(extension);
return extHostEditorInsets.createWebviewEditorInset(editor, line, height, options, extension);
},
createTerminal(nameOrOptions?: vscode.TerminalOptions | vscode.TerminalVirtualProcessOptions | string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal {
createTerminal(nameOrOptions?: vscode.TerminalOptions | vscode.ExtensionTerminalOptions | string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal {
if (typeof nameOrOptions === 'object') {
if ('virtualProcess' in nameOrOptions) {
return extHostTerminalService.createVirtualProcessTerminal(nameOrOptions);
if ('pty' in nameOrOptions) {
return extHostTerminalService.createExtensionTerminal(nameOrOptions);
} else {
nameOrOptions.hideFromUser = nameOrOptions.hideFromUser || (nameOrOptions.runInBackground && extension.enableProposedApi);
return extHostTerminalService.createTerminalFromOptions(nameOrOptions);
......
......@@ -588,7 +588,7 @@ export class ExtHostTask implements ExtHostTaskShape {
// Clone the custom execution to keep the original untouched. This is important for multiple runs of the same task.
this._activeCustomExecutions2.set(execution.id, execution2);
await this._terminalService.attachVirtualProcessToTerminal(terminalId, await execution2.callback());
await this._terminalService.attachPtyToTerminal(terminalId, await execution2.callback());
}
// Once a terminal is spun up for the custom execution task this event will be fired.
......
......@@ -124,8 +124,8 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi
this._runQueuedRequests(terminal.id);
}
public async createVirtualProcess(): Promise<void> {
const terminal = await this._proxy.$createTerminal({ name: this._name, isVirtualProcess: true });
public async createExtensionTerminal(): Promise<void> {
const terminal = await this._proxy.$createTerminal({ name: this._name, isExtensionTerminal: true });
this._name = terminal.name;
this._runQueuedRequests(terminal.id);
}
......@@ -329,20 +329,20 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
return terminal;
}
public createVirtualProcessTerminal(options: vscode.TerminalVirtualProcessOptions): vscode.Terminal {
public createExtensionTerminal(options: vscode.ExtensionTerminalOptions): vscode.Terminal {
const terminal = new ExtHostTerminal(this._proxy, options.name);
const p = new ExtHostVirtualProcess(options.virtualProcess);
terminal.createVirtualProcess().then(() => this._setupExtHostProcessListeners(terminal._id, p));
const p = new ExtHostPseudoterminal(options.pty);
terminal.createExtensionTerminal().then(() => this._setupExtHostProcessListeners(terminal._id, p));
this._terminals.push(terminal);
return terminal;
}
public async attachVirtualProcessToTerminal(id: number, virtualProcess: vscode.TerminalVirtualProcess): Promise<void> {
public async attachPtyToTerminal(id: number, pty: vscode.Pseudoterminal): Promise<void> {
const terminal = this._getTerminalByIdEventually(id);
if (!terminal) {
throw new Error(`Cannot resolve terminal with id ${id} for virtual process`);
}
const p = new ExtHostVirtualProcess(virtualProcess);
const p = new ExtHostPseudoterminal(pty);
this._setupExtHostProcessListeners(id, p);
}
......@@ -550,7 +550,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
this._variableResolver = new ExtHostVariableResolverService(workspaceFolders || [], this._extHostDocumentsAndEditors, configProvider);
}
public async $createProcess(id: number, shellLaunchConfigDto: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise<void> {
public async $spawnExtHostProcess(id: number, shellLaunchConfigDto: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise<void> {
const shellLaunchConfig: IShellLaunchConfig = {
name: shellLaunchConfigDto.name,
executable: shellLaunchConfigDto.executable,
......@@ -619,9 +619,9 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
this._setupExtHostProcessListeners(id, new TerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, enableConpty, this._logService));
}
public async $startVirtualProcess(id: number, initialDimensions: ITerminalDimensionsDto | undefined): Promise<void> {
public async $startExtensionTerminal(id: number, initialDimensions: ITerminalDimensionsDto | undefined): Promise<void> {
// Make sure the ExtHostTerminal exists so onDidOpenTerminal has fired before we call
// TerminalVirtualProcess.start
// Pseudoterminal.start
await this._getTerminalByIdEventually(id);
// Processes should be initialized here for normal virtual process terminals, however for
......@@ -630,7 +630,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
let retries = 5;
while (retries-- > 0) {
if (this._terminalProcesses[id]) {
(this._terminalProcesses[id] as ExtHostVirtualProcess).startSendingEvents(initialDimensions);
(this._terminalProcesses[id] as ExtHostPseudoterminal).startSendingEvents(initialDimensions);
return;
}
await timeout(50);
......@@ -773,7 +773,7 @@ class ApiRequest {
}
}
class ExtHostVirtualProcess implements ITerminalChildProcess {
class ExtHostPseudoterminal implements ITerminalChildProcess {
private _queuedEvents: (IQueuedEvent<string> | IQueuedEvent<number> | IQueuedEvent<{ pid: number, cwd: string }> | IQueuedEvent<ITerminalDimensions | undefined>)[] = [];
private _queueDisposables: IDisposable[] | undefined;
......@@ -789,33 +789,33 @@ class ExtHostVirtualProcess implements ITerminalChildProcess {
public get onProcessOverrideDimensions(): Event<ITerminalDimensions | undefined> { return this._onProcessOverrideDimensions.event; }
constructor(
private readonly _virtualProcess: vscode.TerminalVirtualProcess
private readonly _pty: vscode.Pseudoterminal
) {
this._queueDisposables = [];
this._queueDisposables.push(this._virtualProcess.onDidWrite(e => this._queuedEvents.push({ emitter: this._onProcessData, data: e })));
if (this._virtualProcess.onDidExit) {
this._queueDisposables.push(this._virtualProcess.onDidExit(e => this._queuedEvents.push({ emitter: this._onProcessExit, data: e })));
this._queueDisposables.push(this._pty.onDidWrite(e => this._queuedEvents.push({ emitter: this._onProcessData, data: e })));
if (this._pty.onDidClose) {
this._queueDisposables.push(this._pty.onDidClose(e => this._queuedEvents.push({ emitter: this._onProcessExit, data: 0 })));
}
if (this._virtualProcess.onDidOverrideDimensions) {
this._queueDisposables.push(this._virtualProcess.onDidOverrideDimensions(e => this._queuedEvents.push({ emitter: this._onProcessOverrideDimensions, data: e ? { cols: e.columns, rows: e.rows } : undefined })));
if (this._pty.onDidOverrideDimensions) {
this._queueDisposables.push(this._pty.onDidOverrideDimensions(e => this._queuedEvents.push({ emitter: this._onProcessOverrideDimensions, data: e ? { cols: e.columns, rows: e.rows } : undefined })));
}
}
shutdown(): void {
if (this._virtualProcess.shutdown) {
this._virtualProcess.shutdown();
if (this._pty.close) {
this._pty.close();
}
}
input(data: string): void {
if (this._virtualProcess.handleInput) {
this._virtualProcess.handleInput(data);
if (this._pty.handleInput) {
this._pty.handleInput(data);
}
}
resize(cols: number, rows: number): void {
if (this._virtualProcess.setDimensions) {
this._virtualProcess.setDimensions({ columns: cols, rows });
if (this._pty.setDimensions) {
this._pty.setDimensions({ columns: cols, rows });
}
}
......@@ -838,19 +838,16 @@ class ExtHostVirtualProcess implements ITerminalChildProcess {
this._queueDisposables = undefined;
// Attach the real listeners
this._virtualProcess.onDidWrite(e => this._onProcessData.fire(e));
if (this._virtualProcess.onDidExit) {
this._virtualProcess.onDidExit(e => {
// Ensure only positive exit codes are returned
this._onProcessExit.fire(e >= 0 ? e : 1);
});
this._pty.onDidWrite(e => this._onProcessData.fire(e));
if (this._pty.onDidClose) {
this._pty.onDidClose(e => this._onProcessExit.fire(0));
}
if (this._virtualProcess.onDidOverrideDimensions) {
this._virtualProcess.onDidOverrideDimensions(e => this._onProcessOverrideDimensions.fire(e ? { cols: e.columns, rows: e.rows } : e));
if (this._pty.onDidOverrideDimensions) {
this._pty.onDidOverrideDimensions(e => this._onProcessOverrideDimensions.fire(e ? { cols: e.columns, rows: e.rows } : e));
}
if (this._virtualProcess.start) {
this._virtualProcess.start(initialDimensions);
if (this._pty.open) {
this._pty.open(initialDimensions);
}
}
}
......
......@@ -926,7 +926,7 @@ export class TerminalTaskSystem implements ITaskSystem {
};
} else if (task.command.runtime === RuntimeType.CustomExecution2) {
this.currentTask.shellLaunchConfig = launchConfigs = {
isVirtualProcess: true,
isExtensionTerminal: true,
waitOnExit,
name: this.createTerminalName(task, workspaceFolder),
initialText: task.command.presentation && task.command.presentation.echo ? `\x1b[1m> Executing task: ${task._label} <\x1b[0m\n` : undefined
......
......@@ -31,7 +31,7 @@ const LATENCY_MEASURING_INTERVAL = 1000;
enum ProcessType {
Process,
VirtualProcess
ExtensionTerminal
}
/**
......@@ -113,8 +113,8 @@ export class TerminalProcessManager implements ITerminalProcessManager {
rows: number,
isScreenReaderModeEnabled: boolean
): Promise<void> {
if (shellLaunchConfig.isVirtualProcess) {
this._processType = ProcessType.VirtualProcess;
if (shellLaunchConfig.isExtensionTerminal) {
this._processType = ProcessType.ExtensionTerminal;
this._process = this._instantiationService.createInstance(TerminalProcessExtHostProxy, this._terminalId, shellLaunchConfig, undefined, cols, rows, this._configHelper);
} else {
const forceExtHostProcess = (this._configHelper.config as any).extHostProcess;
......@@ -239,7 +239,7 @@ export class TerminalProcessManager implements ITerminalProcessManager {
}
public write(data: string): void {
if (this.shellProcessId || this._processType === ProcessType.VirtualProcess) {
if (this.shellProcessId || this._processType === ProcessType.ExtensionTerminal) {
if (this._process) {
// Send data if the pty is ready
this._process.input(data);
......@@ -292,4 +292,4 @@ export class TerminalProcessManager implements ITerminalProcessManager {
this._onProcessExit.fire(exitCode);
}
}
\ No newline at end of file
}
......@@ -188,14 +188,14 @@ export interface IShellLaunchConfig {
initialText?: string;
/**
* @deprecated use `isVirtualProcess`
* @deprecated use `isExtensionTerminal`
*/
isRendererOnly?: boolean;
/**
* When true an extension is acting as the terminal's process.
* Whether an extension is controlling the terminal via a `vscode.Pseudoterminal`.
*/
isVirtualProcess?: boolean;
isExtensionTerminal?: boolean;
/**
* Whether the terminal process environment should be exactly as provided in
......@@ -231,8 +231,8 @@ export interface ITerminalService {
onInstanceProcessIdReady: Event<ITerminalInstance>;
onInstanceDimensionsChanged: Event<ITerminalInstance>;
onInstanceMaximumDimensionsChanged: Event<ITerminalInstance>;
onInstanceRequestExtHostProcess: Event<ITerminalProcessExtHostRequest>;
onInstanceRequestVirtualProcess: Event<ITerminalVirtualProcessRequest>;
onInstanceRequestSpawnExtHostProcess: Event<ISpawnExtHostProcessRequest>;
onInstanceRequestStartExtensionTerminal: Event<IStartExtensionTerminalRequest>;
onInstancesChanged: Event<void>;
onInstanceTitleChanged: Event<ITerminalInstance>;
onActiveInstanceChanged: Event<ITerminalInstance | undefined>;
......@@ -299,8 +299,8 @@ export interface ITerminalService {
preparePathForTerminalAsync(path: string, executable: string | undefined, title: string): Promise<string>;
extHostReady(remoteAuthority: string): void;
requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void;
requestVirtualProcess(proxy: ITerminalProcessExtHostProxy, cols: number, rows: number): void;
requestSpawnExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void;
requestStartExtensionTerminal(proxy: ITerminalProcessExtHostProxy, cols: number, rows: number): void;
}
/**
......@@ -760,7 +760,7 @@ export interface ITerminalProcessExtHostProxy extends IDisposable {
onRequestLatency: Event<void>;
}
export interface ITerminalProcessExtHostRequest {
export interface ISpawnExtHostProcessRequest {
proxy: ITerminalProcessExtHostProxy;
shellLaunchConfig: IShellLaunchConfig;
activeWorkspaceRootUri: URI;
......@@ -769,7 +769,7 @@ export interface ITerminalProcessExtHostRequest {
isWorkspaceShellAllowed: boolean;
}
export interface ITerminalVirtualProcessRequest {
export interface IStartExtensionTerminalRequest {
proxy: ITerminalProcessExtHostProxy;
cols: number;
rows: number;
......
......@@ -58,14 +58,14 @@ export class TerminalProcessExtHostProxy extends Disposable implements ITerminal
// Request a process if needed, if this is a virtual process this step can be skipped as
// there is no real "process" and we know it's ready on the ext host already.
if (shellLaunchConfig.isVirtualProcess) {
this._terminalService.requestVirtualProcess(this, cols, rows);
if (shellLaunchConfig.isExtensionTerminal) {
this._terminalService.requestStartExtensionTerminal(this, cols, rows);
} else {
remoteAgentService.getEnvironment().then(env => {
if (!env) {
throw new Error('Could not fetch environment');
}
this._terminalService.requestExtHostProcess(this, shellLaunchConfig, activeWorkspaceRootUri, cols, rows, configHelper.checkWorkspaceShellPermissions(env.os));
this._terminalService.requestSpawnExtHostProcess(this, shellLaunchConfig, activeWorkspaceRootUri, cols, rows, configHelper.checkWorkspaceShellPermissions(env.os));
});
if (!hasReceivedResponse) {
setTimeout(() => this._onProcessTitleChanged.fire(nls.localize('terminal.integrated.starting', "Starting...")), 0);
......@@ -149,4 +149,4 @@ export class TerminalProcessExtHostProxy extends Disposable implements ITerminal
this._pendingLatencyRequests.push(resolve);
});
}
}
\ No newline at end of file
}
......@@ -8,7 +8,7 @@ import { Event, Emitter } from 'vs/base/common/event';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalConfigHelper, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, TERMINAL_PANEL_ID, ITerminalTab, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN, ITerminalNativeService, IShellDefinition, IAvailableShellsRequest, ITerminalVirtualProcessRequest } from 'vs/workbench/contrib/terminal/common/terminal';
import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalConfigHelper, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, TERMINAL_PANEL_ID, ITerminalTab, ITerminalProcessExtHostProxy, ISpawnExtHostProcessRequest, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN, ITerminalNativeService, IShellDefinition, IAvailableShellsRequest, IStartExtensionTerminalRequest } from 'vs/workbench/contrib/terminal/common/terminal';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { URI } from 'vs/base/common/uri';
import { FindReplaceState } from 'vs/editor/contrib/find/findState';
......@@ -53,10 +53,10 @@ export abstract class TerminalService implements ITerminalService {
public get onInstanceDisposed(): Event<ITerminalInstance> { return this._onInstanceDisposed.event; }
protected readonly _onInstanceProcessIdReady = new Emitter<ITerminalInstance>();
public get onInstanceProcessIdReady(): Event<ITerminalInstance> { return this._onInstanceProcessIdReady.event; }
protected readonly _onInstanceRequestExtHostProcess = new Emitter<ITerminalProcessExtHostRequest>();
public get onInstanceRequestExtHostProcess(): Event<ITerminalProcessExtHostRequest> { return this._onInstanceRequestExtHostProcess.event; }
protected readonly _onInstanceRequestVirtualProcess = new Emitter<ITerminalVirtualProcessRequest>();
public get onInstanceRequestVirtualProcess(): Event<ITerminalVirtualProcessRequest> { return this._onInstanceRequestVirtualProcess.event; }
protected readonly _onInstanceRequestSpawnExtHostProcess = new Emitter<ISpawnExtHostProcessRequest>();
public get onInstanceRequestSpawnExtHostProcess(): Event<ISpawnExtHostProcessRequest> { return this._onInstanceRequestSpawnExtHostProcess.event; }
protected readonly _onInstanceRequestStartExtensionTerminal = new Emitter<IStartExtensionTerminalRequest>();
public get onInstanceRequestStartExtensionTerminal(): Event<IStartExtensionTerminalRequest> { return this._onInstanceRequestStartExtensionTerminal.event; }
protected readonly _onInstanceDimensionsChanged = new Emitter<ITerminalInstance>();
public get onInstanceDimensionsChanged(): Event<ITerminalInstance> { return this._onInstanceDimensionsChanged.event; }
protected readonly _onInstanceMaximumDimensionsChanged = new Emitter<ITerminalInstance>();
......@@ -131,7 +131,7 @@ export abstract class TerminalService implements ITerminalService {
return activeInstance ? activeInstance : this.createTerminal(undefined, wasNewTerminalAction);
}
public requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void {
public requestSpawnExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void {
this._extensionService.whenInstalledExtensionsRegistered().then(async () => {
// Wait for the remoteAuthority to be ready (and listening for events) before proceeding
const conn = this._remoteAgentService.getConnection();
......@@ -140,12 +140,12 @@ export abstract class TerminalService implements ITerminalService {
while (!this._extHostsReady[remoteAuthority] && ++retries < 50) {
await timeout(100);
}
this._onInstanceRequestExtHostProcess.fire({ proxy, shellLaunchConfig, activeWorkspaceRootUri, cols, rows, isWorkspaceShellAllowed });
this._onInstanceRequestSpawnExtHostProcess.fire({ proxy, shellLaunchConfig, activeWorkspaceRootUri, cols, rows, isWorkspaceShellAllowed });
});
}
public requestVirtualProcess(proxy: ITerminalProcessExtHostProxy, cols: number, rows: number): void {
this._onInstanceRequestVirtualProcess.fire({ proxy, cols, rows });
public requestStartExtensionTerminal(proxy: ITerminalProcessExtHostProxy, cols: number, rows: number): void {
this._onInstanceRequestStartExtensionTerminal.fire({ proxy, cols, rows });
}
public extHostReady(remoteAuthority: string): void {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册