提交 7236f593 编写于 作者: D Daniel Imms

Implement vscode.Terminal.processId

Fixes #11919
上级 1cc8b7c8
......@@ -3012,6 +3012,13 @@ declare namespace vscode {
*/
name: string;
/**
* The process ID of the shell process.
*
* @readonly
*/
processId: Thenable<number>;
/**
* Send text to the terminal. The text is written to the stdin of the underlying pty process
* (shell) of the terminal.
......
......@@ -312,6 +312,7 @@ export abstract class ExtHostQuickOpenShape {
export abstract class ExtHostTerminalServiceShape {
$acceptTerminalClosed(id: number): void { throw ni(); }
$acceptTerminalProcessId(id: number, processId: number): void { throw ni(); }
}
// --- proxy identifiers
......
......@@ -13,6 +13,7 @@ export class ExtHostTerminal implements vscode.Terminal {
private _name: string;
private _id: number;
private _processId: number;
private _proxy: MainThreadTerminalServiceShape;
private _disposed: boolean;
private _queuedRequests: ApiRequest[];
......@@ -34,6 +35,16 @@ export class ExtHostTerminal implements vscode.Terminal {
return this._name;
}
public get processId(): Thenable<number> {
this._checkDisposed();
if (this._processId) {
return Promise.resolve<number>(this._processId);
}
setTimeout(() => {
return this.processId;
}, 200);
}
public sendText(text: string, addNewLine: boolean = true): void {
this._checkDisposed();
this._queueApiRequest(this._proxy.$sendText, [text, addNewLine]);
......@@ -56,6 +67,10 @@ export class ExtHostTerminal implements vscode.Terminal {
}
}
public setProcessId(processId: number): void {
this._processId = processId;
}
private _queueApiRequest(callback: (...args: any[]) => void, args: any[]) {
let request: ApiRequest = new ApiRequest(callback, args);
if (!this._id) {
......@@ -104,6 +119,16 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
this._onDidCloseTerminal.fire(terminal);
}
public $acceptTerminalProcessId(id: number, processId: number): void {
let terminal = this._getTerminalById(id);
terminal.setProcessId(processId);
}
private _getTerminalById(id: number): ExtHostTerminal {
let index = this._getTerminalIndexById(id);
return index !== null ? this._terminals[index] : null;
}
private _getTerminalIndexById(id: number): number {
let index: number = null;
this._terminals.some((terminal, i) => {
......@@ -118,6 +143,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
}
class ApiRequest {
private _callback: (...args: any[]) => void;
private _args: any[];
......
......@@ -27,6 +27,7 @@ export class MainThreadTerminalService extends MainThreadTerminalServiceShape {
this._proxy = threadService.get(ExtHostContext.ExtHostTerminalService);
this._toDispose = [];
this._toDispose.push(terminalService.onInstanceDisposed((terminalInstance) => this._onTerminalDisposed(terminalInstance)));
this._toDispose.push(terminalService.onInstanceProcessIdReady((terminalInstance) => this._onTerminalProcessIdReady(terminalInstance)));
}
public dispose(): void {
......@@ -68,4 +69,8 @@ export class MainThreadTerminalService extends MainThreadTerminalServiceShape {
private _onTerminalDisposed(terminalInstance: ITerminalInstance): void {
this._proxy.$acceptTerminalClosed(terminalInstance.id);
}
private _onTerminalProcessIdReady(terminalInstance: ITerminalInstance): void {
this._proxy.$acceptTerminalProcessId(terminalInstance.id, terminalInstance.processId);
}
}
......@@ -59,6 +59,7 @@ export interface ITerminalService {
configHelper: TerminalConfigHelper;
onActiveInstanceChanged: Event<string>;
onInstanceDisposed: Event<ITerminalInstance>;
onInstanceProcessIdReady: Event<ITerminalInstance>;
onInstancesChanged: Event<string>;
onInstanceTitleChanged: Event<string>;
terminalInstances: ITerminalInstance[];
......@@ -85,6 +86,11 @@ export interface ITerminalInstance {
*/
id: number;
/**
* The process ID of the shell process.
*/
processId: number;
/**
* An event that fires when the terminal instance's title changes.
*/
......
......@@ -34,8 +34,10 @@ export class TerminalInstance implements ITerminalInstance {
private _isExiting: boolean;
private _isVisible: boolean;
private _onDisposed: Emitter<TerminalInstance>;
private _onProcessIdReady: Emitter<TerminalInstance>;
private _onTitleChanged: Emitter<string>;
private _process: cp.ChildProcess;
private _processId: number;
private _skipTerminalKeybindings: Keybinding[];
private _title: string;
private _toDispose: lifecycle.IDisposable[];
......@@ -44,7 +46,9 @@ export class TerminalInstance implements ITerminalInstance {
private _xtermElement: HTMLDivElement;
public get id(): number { return this._id; }
public get processId(): number { return this._processId; }
public get onClosed(): Event<TerminalInstance> { return this._onDisposed.event; }
public get onProcessIdReady(): Event<TerminalInstance> { return this._onProcessIdReady.event; }
public get onTitleChanged(): Event<string> { return this._onTitleChanged.event; }
public get title(): string { return this._title; }
......@@ -64,8 +68,9 @@ export class TerminalInstance implements ITerminalInstance {
this._isVisible = false;
this._id = TerminalInstance._idCounter++;
this._onTitleChanged = new Emitter<string>();
this._onDisposed = new Emitter<TerminalInstance>();
this._onProcessIdReady = new Emitter<TerminalInstance>();
this._onTitleChanged = new Emitter<string>();
this._createProcess(_workspace, name, shell);
......@@ -94,6 +99,9 @@ export class TerminalInstance implements ITerminalInstance {
this._process.on('message', (message) => {
if (message.type === 'data') {
this._xterm.write(message.content);
} else if (message.type === 'pid') {
this._processId = message.content;
this._onProcessIdReady.fire(this);
}
});
this._xterm.on('data', (data) => {
......
......@@ -51,6 +51,7 @@ process.on('message', function (message) {
}
});
sendProcessId();
setupTitlePolling();
function getArgs() {
......@@ -91,6 +92,13 @@ function setupPlanB(parentPid) {
}, 5000);
}
function sendProcessId() {
process.send({
type: 'pid',
content: ptyProcess.pid
});
}
function setupTitlePolling() {
sendProcessTitle();
setInterval(function () {
......
......@@ -24,6 +24,7 @@ export class TerminalService implements ITerminalService {
private _configHelper: TerminalConfigHelper;
private _onActiveInstanceChanged: Emitter<string>;
private _onInstanceDisposed: Emitter<ITerminalInstance>;
private _onInstanceProcessIdReady: Emitter<ITerminalInstance>;
private _onInstanceTitleChanged: Emitter<string>;
private _onInstancesChanged: Emitter<string>;
private _terminalContainer: HTMLElement;
......@@ -34,6 +35,7 @@ export class TerminalService implements ITerminalService {
public get configHelper(): TerminalConfigHelper { return this._configHelper; }
public get onActiveInstanceChanged(): Event<string> { return this._onActiveInstanceChanged.event; }
public get onInstanceDisposed(): Event<ITerminalInstance> { return this._onInstanceDisposed.event; }
public get onInstanceProcessIdReady(): Event<ITerminalInstance> { return this._onInstanceProcessIdReady.event; }
public get onInstanceTitleChanged(): Event<string> { return this._onInstanceTitleChanged.event; }
public get onInstancesChanged(): Event<string> { return this._onInstancesChanged.event; }
public get terminalInstances(): ITerminalInstance[] { return this._terminalInstances; }
......@@ -51,8 +53,9 @@ export class TerminalService implements ITerminalService {
this._onActiveInstanceChanged = new Emitter<string>();
this._onInstanceDisposed = new Emitter<ITerminalInstance>();
this._onInstancesChanged = new Emitter<string>();
this._onInstanceProcessIdReady = new Emitter<ITerminalInstance>();
this._onInstanceTitleChanged = new Emitter<string>();
this._onInstancesChanged = new Emitter<string>();
this._terminalFocusContextKey = KEYBINDING_CONTEXT_TERMINAL_FOCUS.bindTo(this._contextKeyService);
this._configHelper = <TerminalConfigHelper>this._instantiationService.createInstance(TerminalConfigHelper, platform.platform);
......@@ -73,6 +76,7 @@ export class TerminalService implements ITerminalService {
shell);
terminalInstance.addDisposable(terminalInstance.onTitleChanged(this._onInstanceTitleChanged.fire, this._onInstanceTitleChanged));
terminalInstance.addDisposable(terminalInstance.onClosed(this._onInstanceDisposed.fire, this._onInstanceDisposed));
terminalInstance.addDisposable(terminalInstance.onProcessIdReady(this._onInstanceProcessIdReady.fire, this._onInstanceProcessIdReady));
this.terminalInstances.push(terminalInstance);
if (this.terminalInstances.length === 1) {
// It's the first instance so it should be made active automatically
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册