提交 70b22b8c 编写于 作者: D Daniel Imms

Get terminal process running on ext host

上级 4323d933
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
'use strict'; 'use strict';
import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ITerminalService, ITerminalInstance, IShellLaunchConfig } from 'vs/workbench/parts/terminal/common/terminal'; import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalProcessExtHostProxy } from 'vs/workbench/parts/terminal/common/terminal';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, IExtHostContext } from '../node/extHost.protocol'; import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, IExtHostContext } from '../node/extHost.protocol';
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
...@@ -14,23 +14,24 @@ import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostC ...@@ -14,23 +14,24 @@ import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostC
export class MainThreadTerminalService implements MainThreadTerminalServiceShape { export class MainThreadTerminalService implements MainThreadTerminalServiceShape {
private _proxy: ExtHostTerminalServiceShape; private _proxy: ExtHostTerminalServiceShape;
private _toDispose: IDisposable[]; private _toDispose: IDisposable[] = [];
private _terminalProcesses: { [id: number]: ITerminalProcessExtHostProxy } = {};
constructor( constructor(
extHostContext: IExtHostContext, extHostContext: IExtHostContext,
@ITerminalService private terminalService: ITerminalService @ITerminalService private terminalService: ITerminalService
) { ) {
console.log('MainThreadTerminalService#ctor');
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTerminalService); this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTerminalService);
this._toDispose = [];
this._toDispose.push(terminalService.onInstanceCreated((terminalInstance) => { this._toDispose.push(terminalService.onInstanceCreated((terminalInstance) => {
// Delay this message so the TerminalInstance constructor has a chance to finish and // Delay this message so the TerminalInstance constructor has a chance to finish and
// return the ID normally to the extension host. The ID that is passed here will be used // return the ID normally to the extension host. The ID that is passed here will be used
// to register non-extension API terminals in the extension host. // to register non-extension API terminals in the extension host.
setTimeout(() => this._onTerminalOpened(terminalInstance), 100); setTimeout(() => this._onTerminalOpened(terminalInstance), 100);
})); }));
this._toDispose.push(terminalService.onInstanceDisposed((terminalInstance) => this._onTerminalDisposed(terminalInstance))); this._toDispose.push(terminalService.onInstanceDisposed(terminalInstance => this._onTerminalDisposed(terminalInstance)));
this._toDispose.push(terminalService.onInstanceProcessIdReady((terminalInstance) => this._onTerminalProcessIdReady(terminalInstance))); this._toDispose.push(terminalService.onInstanceProcessIdReady(terminalInstance => this._onTerminalProcessIdReady(terminalInstance)));
this._toDispose.push(terminalService.onInstanceRequestExtHostProcess((terminalInstance) => this._onTerminalRequestExtHostProcess(terminalInstance))); this._toDispose.push(terminalService.onInstanceRequestExtHostProcess(proxy => this._onTerminalRequestExtHostProcess(proxy)));
// Set initial ext host state // Set initial ext host state
this.terminalService.terminalInstances.forEach(t => { this.terminalService.terminalInstances.forEach(t => {
...@@ -99,8 +100,27 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape ...@@ -99,8 +100,27 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
this._proxy.$acceptTerminalProcessId(terminalInstance.id, terminalInstance.processId); this._proxy.$acceptTerminalProcessId(terminalInstance.id, terminalInstance.processId);
} }
private _onTerminalRequestExtHostProcess(terminalInstance: ITerminalInstance): void { private _onTerminalRequestExtHostProcess(proxy: ITerminalProcessExtHostProxy): void {
console.log('mainThreadTerminalService#_onTerminalRequestExtHostProcess', arguments); console.log('mainThreadTerminalService#_onTerminalRequestExtHostProcess', arguments);
this._proxy.$createProcess(null, 0, 0); this._terminalProcesses[proxy.terminalId] = proxy;
this._proxy.$createProcess(proxy.terminalId, null, 0, 0);
// TODO: Dispose of this properly when the terminal/process dies
this._toDispose.push(proxy.onInput(data => this._onTerminalProcessWrite(proxy.terminalId, data)));
}
public $sendProcessTitle(terminalId: number, title: string): void {
this._terminalProcesses[terminalId].emitTitle(title);
}
public $sendProcessData(terminalId: number, data: string): void {
this._terminalProcesses[terminalId].emitData(data);
}
public $sendProcessPid(terminalId: number, pid: number): void {
this._terminalProcesses[terminalId].emitPid(pid);
}
private _onTerminalProcessWrite(terminalId: number, data: string): void {
this._proxy.$acceptTerminalProcessWrite(terminalId, data);
} }
} }
...@@ -321,6 +321,10 @@ export interface MainThreadTerminalServiceShape extends IDisposable { ...@@ -321,6 +321,10 @@ export interface MainThreadTerminalServiceShape extends IDisposable {
$hide(terminalId: number): void; $hide(terminalId: number): void;
$sendText(terminalId: number, text: string, addNewLine: boolean): void; $sendText(terminalId: number, text: string, addNewLine: boolean): void;
$show(terminalId: number, preserveFocus: boolean): void; $show(terminalId: number, preserveFocus: boolean): void;
$sendProcessTitle(terminalId: number, title: string): void;
$sendProcessData(terminalId: number, data: string): void;
$sendProcessPid(terminalId: number, pid: number): void;
} }
export interface MyQuickPickItems extends IPickOpenEntry { export interface MyQuickPickItems extends IPickOpenEntry {
...@@ -743,7 +747,8 @@ export interface ExtHostTerminalServiceShape { ...@@ -743,7 +747,8 @@ export interface ExtHostTerminalServiceShape {
$acceptTerminalClosed(id: number): void; $acceptTerminalClosed(id: number): void;
$acceptTerminalOpened(id: number, name: string): void; $acceptTerminalOpened(id: number, name: string): void;
$acceptTerminalProcessId(id: number, processId: number): void; $acceptTerminalProcessId(id: number, processId: number): void;
$createProcess(shellLaunchConfig: ShellLaunchConfigDto, cols: number, rows: number): void; $createProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, cols: number, rows: number): void;
$acceptTerminalProcessWrite(id: number, data: string): void;
} }
export interface ExtHostSCMShape { export interface ExtHostSCMShape {
......
...@@ -5,8 +5,12 @@ ...@@ -5,8 +5,12 @@
'use strict'; 'use strict';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as cp from 'child_process';
import * as path from 'path';
import * as terminalEnvironment from 'vs/workbench/parts/terminal/node/terminalEnvironment';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto } from 'vs/workbench/api/node/extHost.protocol'; import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto } from 'vs/workbench/api/node/extHost.protocol';
import { IMessageFromTerminalProcess } from 'vs/workbench/parts/terminal/node/terminal';
export class ExtHostTerminal implements vscode.Terminal { export class ExtHostTerminal implements vscode.Terminal {
...@@ -81,6 +85,7 @@ export class ExtHostTerminal implements vscode.Terminal { ...@@ -81,6 +85,7 @@ export class ExtHostTerminal implements vscode.Terminal {
} }
public _setProcessId(processId: number): void { public _setProcessId(processId: number): void {
console.log('extHostTerminalService#_setProcessId', processId);
this._pidPromiseComplete(processId); this._pidPromiseComplete(processId);
this._pidPromiseComplete = null; this._pidPromiseComplete = null;
} }
...@@ -106,7 +111,8 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { ...@@ -106,7 +111,8 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
private readonly _onDidCloseTerminal: Emitter<vscode.Terminal>; private readonly _onDidCloseTerminal: Emitter<vscode.Terminal>;
private readonly _onDidOpenTerminal: Emitter<vscode.Terminal>; private readonly _onDidOpenTerminal: Emitter<vscode.Terminal>;
private _proxy: MainThreadTerminalServiceShape; private _proxy: MainThreadTerminalServiceShape;
private _terminals: ExtHostTerminal[]; private _terminals: ExtHostTerminal[] = [];
private _terminalProcesses: { [id: number]: cp.ChildProcess } = {};
public get terminals(): ExtHostTerminal[] { return this._terminals; } public get terminals(): ExtHostTerminal[] { return this._terminals; }
...@@ -114,7 +120,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { ...@@ -114,7 +120,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
this._onDidCloseTerminal = new Emitter<vscode.Terminal>(); this._onDidCloseTerminal = new Emitter<vscode.Terminal>();
this._onDidOpenTerminal = new Emitter<vscode.Terminal>(); this._onDidOpenTerminal = new Emitter<vscode.Terminal>();
this._proxy = mainContext.getProxy(MainContext.MainThreadTerminalService); this._proxy = mainContext.getProxy(MainContext.MainThreadTerminalService);
this._terminals = [];
} }
public createTerminal(name?: string, shellPath?: string, shellArgs?: string[]): vscode.Terminal { public createTerminal(name?: string, shellPath?: string, shellArgs?: string[]): vscode.Terminal {
...@@ -150,6 +155,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { ...@@ -150,6 +155,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
} }
public $acceptTerminalOpened(id: number, name: string): void { public $acceptTerminalOpened(id: number, name: string): void {
console.log('terminal opened: ' + id);
let index = this._getTerminalIndexById(id); let index = this._getTerminalIndexById(id);
if (index !== null) { if (index !== null) {
// The terminal has already been created (via createTerminal*), only fire the event // The terminal has already been created (via createTerminal*), only fire the event
...@@ -163,13 +169,64 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { ...@@ -163,13 +169,64 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
public $acceptTerminalProcessId(id: number, processId: number): void { public $acceptTerminalProcessId(id: number, processId: number): void {
let terminal = this._getTerminalById(id); let terminal = this._getTerminalById(id);
console.log('ExtHostTerminalService#$acceptTerminalProcessId ' + id + ' ' + processId);
if (terminal) { if (terminal) {
terminal._setProcessId(processId); terminal._setProcessId(processId);
} }
} }
public $createProcess(shellLaunchConfig: ShellLaunchConfigDto, cols: number, rows: number): void { public $createProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, cols: number, rows: number): void {
console.log('$createProcess'); shellLaunchConfig = {
env: {},
executable: 'bash'
};
// TODO: Launch process
// TODO: Associate the process with the terminal object/id
// TODO: terminal has incorrect name/options, fix up
const parentEnv = { ...process.env };
const env = terminalEnvironment.createTerminalEnv(parentEnv, shellLaunchConfig, '/home/daniel', undefined, cols, rows);
// TODO: Use Uri?
let cwd = path.dirname(require.toUrl('../../parts/terminal/node/terminalProcess')).replace('file://', '');
console.log(cwd);
const options = { env, cwd, execArgv: [] };
let bootstrapUri = require.toUrl('bootstrap').replace('file://', '') + '.js';
console.log(bootstrapUri);
// cwd = '/home/daniel/dev/Microsoft/vscode/out/vs/workbench/parts/terminal/node';
// bootstrapUri = '/home/daniel/dev/Microsoft/vscode/out/bootstrap';
// env['AMD_ENTRYPOINT'] = 'vs/workbench/parts/terminal/node/terminalProcess';
this._terminalProcesses[id] = cp.fork(bootstrapUri, ['--type=terminal'], options);
this._terminalProcesses[id].on('message', (message: IMessageFromTerminalProcess) => {
switch (message.type) {
case 'pid':
this._proxy.$sendProcessPid(id, <number>message.content);
break;
case 'title':
this._proxy.$sendProcessTitle(id, <string>message.content);
break;
case 'data':
this._proxy.$sendProcessData(id, <string>message.content);
break;
}
// console.log('message type: ' + d.type + ', content: ' + d.content)
});
// const processPath = require.toUrl('../../parts/terminal/node/terminalProcess').replace('file://', '');
// const process2 = cp.fork(processPath, [], options);
// process2.on('data', d => console.log('data ' + d));
// process2.on('exit', d => console.log('exit ' + d));
// process2.on('error', d => console.log('error ' + d));
const terminal = this._getTerminalById(id);
console.log('$createProcess terminal: ' + terminal.name);
}
public $acceptTerminalProcessWrite(id: number, data: string): void {
this._terminalProcesses[id].send({ event: 'input', data });
} }
private _getTerminalById(id: number): ExtHostTerminal { private _getTerminalById(id: number): ExtHostTerminal {
...@@ -180,6 +237,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { ...@@ -180,6 +237,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
private _getTerminalIndexById(id: number): number { private _getTerminalIndexById(id: number): number {
let index: number = null; let index: number = null;
this._terminals.some((terminal, i) => { this._terminals.some((terminal, i) => {
// TODO: This shouldn't be cas
let thisId = (<any>terminal)._id; let thisId = (<any>terminal)._id;
if (thisId === id) { if (thisId === id) {
index = i; index = i;
......
...@@ -165,7 +165,7 @@ export interface ITerminalService { ...@@ -165,7 +165,7 @@ export interface ITerminalService {
onInstanceCreated: Event<ITerminalInstance>; onInstanceCreated: Event<ITerminalInstance>;
onInstanceDisposed: Event<ITerminalInstance>; onInstanceDisposed: Event<ITerminalInstance>;
onInstanceProcessIdReady: Event<ITerminalInstance>; onInstanceProcessIdReady: Event<ITerminalInstance>;
onInstanceRequestExtHostProcess: Event<ITerminalInstance>; onInstanceRequestExtHostProcess: Event<ITerminalProcessExtHostProxy>;
onInstancesChanged: Event<void>; onInstancesChanged: Event<void>;
onInstanceTitleChanged: Event<string>; onInstanceTitleChanged: Event<string>;
terminalInstances: ITerminalInstance[]; terminalInstances: ITerminalInstance[];
...@@ -207,7 +207,7 @@ export interface ITerminalService { ...@@ -207,7 +207,7 @@ export interface ITerminalService {
selectDefaultWindowsShell(): TPromise<string>; selectDefaultWindowsShell(): TPromise<string>;
setWorkspaceShellAllowed(isAllowed: boolean): void; setWorkspaceShellAllowed(isAllowed: boolean): void;
requestExtHostProcess(proxy: ITerminalProcessExtHostProxy): TPromise<void>; requestExtHostProcess(proxy: ITerminalProcessExtHostProxy): void;
} }
export const enum Direction { export const enum Direction {
...@@ -524,7 +524,10 @@ export enum ProcessState { ...@@ -524,7 +524,10 @@ export enum ProcessState {
export interface ITerminalProcessExtHostProxy { export interface ITerminalProcessExtHostProxy {
readonly terminalId: number;
emitData(data: string): void; emitData(data: string): void;
emitTitle(title: string): void; emitTitle(title: string): void;
emitPid(pid: number): void; emitPid(pid: number): void;
} onInput(listener: (data: string) => void): IDisposable;
\ No newline at end of file }
...@@ -39,8 +39,8 @@ export abstract class TerminalService implements ITerminalService { ...@@ -39,8 +39,8 @@ export abstract class TerminalService implements ITerminalService {
public get onInstanceDisposed(): Event<ITerminalInstance> { return this._onInstanceDisposed.event; } public get onInstanceDisposed(): Event<ITerminalInstance> { return this._onInstanceDisposed.event; }
protected readonly _onInstanceProcessIdReady: Emitter<ITerminalInstance> = new Emitter<ITerminalInstance>(); protected readonly _onInstanceProcessIdReady: Emitter<ITerminalInstance> = new Emitter<ITerminalInstance>();
public get onInstanceProcessIdReady(): Event<ITerminalInstance> { return this._onInstanceProcessIdReady.event; } public get onInstanceProcessIdReady(): Event<ITerminalInstance> { return this._onInstanceProcessIdReady.event; }
protected readonly _onInstanceRequestExtHostProcess: Emitter<ITerminalInstance> = new Emitter<ITerminalInstance>(); protected readonly _onInstanceRequestExtHostProcess: Emitter<ITerminalProcessExtHostProxy> = new Emitter<ITerminalProcessExtHostProxy>();
public get onInstanceRequestExtHostProcess(): Event<ITerminalInstance> { return this._onInstanceRequestExtHostProcess.event; } public get onInstanceRequestExtHostProcess(): Event<ITerminalProcessExtHostProxy> { return this._onInstanceRequestExtHostProcess.event; }
protected readonly _onInstancesChanged: Emitter<void> = new Emitter<void>(); protected readonly _onInstancesChanged: Emitter<void> = new Emitter<void>();
public get onInstancesChanged(): Event<void> { return this._onInstancesChanged.event; } public get onInstancesChanged(): Event<void> { return this._onInstancesChanged.event; }
protected readonly _onInstanceTitleChanged: Emitter<string> = new Emitter<string>(); protected readonly _onInstanceTitleChanged: Emitter<string> = new Emitter<string>();
...@@ -75,7 +75,7 @@ export abstract class TerminalService implements ITerminalService { ...@@ -75,7 +75,7 @@ export abstract class TerminalService implements ITerminalService {
public abstract getActiveOrCreateInstance(wasNewTerminalAction?: boolean): ITerminalInstance; public abstract getActiveOrCreateInstance(wasNewTerminalAction?: boolean): ITerminalInstance;
public abstract selectDefaultWindowsShell(): TPromise<string>; public abstract selectDefaultWindowsShell(): TPromise<string>;
public abstract setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; public abstract setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void;
public abstract requestExtHostProcess(proxy: ITerminalProcessExtHostProxy): TPromise<void>; public abstract requestExtHostProcess(proxy: ITerminalProcessExtHostProxy): void;
private _restoreTabs(): void { private _restoreTabs(): void {
if (!this.configHelper.config.experimentalRestore) { if (!this.configHelper.config.experimentalRestore) {
......
...@@ -587,7 +587,7 @@ export class TerminalInstance implements ITerminalInstance { ...@@ -587,7 +587,7 @@ export class TerminalInstance implements ITerminalInstance {
} }
protected _createProcess(): void { protected _createProcess(): void {
this._processManager = this._instantiationService.createInstance(TerminalProcessManager, this._configHelper); this._processManager = this._instantiationService.createInstance(TerminalProcessManager, this._id, this._configHelper);
this._processManager.onProcessReady(() => this._onProcessIdReady.fire(this)); this._processManager.onProcessReady(() => this._onProcessIdReady.fire(this));
this._processManager.onProcessExit(exitCode => this._onProcessExit(exitCode)); this._processManager.onProcessExit(exitCode => this._onProcessExit(exitCode));
this._processManager.createProcess(this._shellLaunchConfig, this._cols, this._rows); this._processManager.createProcess(this._shellLaunchConfig, this._cols, this._rows);
......
...@@ -51,6 +51,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { ...@@ -51,6 +51,7 @@ export class TerminalProcessManager implements ITerminalProcessManager {
public get onProcessExit(): Event<number> { return this._onProcessExit.event; } public get onProcessExit(): Event<number> { return this._onProcessExit.event; }
constructor( constructor(
private _terminalId: number,
private _configHelper: ITerminalConfigHelper, private _configHelper: ITerminalConfigHelper,
@IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService, @IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService,
@IHistoryService private readonly _historyService: IHistoryService, @IHistoryService private readonly _historyService: IHistoryService,
...@@ -117,7 +118,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { ...@@ -117,7 +118,7 @@ export class TerminalProcessManager implements ITerminalProcessManager {
const options = { env, cwd }; const options = { env, cwd };
this._logService.debug(`Terminal process launching`, options); this._logService.debug(`Terminal process launching`, options);
if (shellLaunchConfig.extensionHostOwned) { if (shellLaunchConfig.extensionHostOwned) {
this._process = this._instantiationService.createInstance(TerminalProcessExtHostProxy); this._process = this._instantiationService.createInstance(TerminalProcessExtHostProxy, this._terminalId);
} else { } else {
this._process = cp.fork(Uri.parse(require.toUrl('bootstrap')).fsPath, ['--type=terminal'], options); this._process = cp.fork(Uri.parse(require.toUrl('bootstrap')).fsPath, ['--type=terminal'], options);
} }
......
...@@ -27,6 +27,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati ...@@ -27,6 +27,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
import { ipcRenderer as ipc } from 'electron'; import { ipcRenderer as ipc } from 'electron';
import { IOpenFileRequest } from 'vs/platform/windows/common/windows'; import { IOpenFileRequest } from 'vs/platform/windows/common/windows';
import { TerminalInstance } from 'vs/workbench/parts/terminal/electron-browser/terminalInstance'; import { TerminalInstance } from 'vs/workbench/parts/terminal/electron-browser/terminalInstance';
import { IExtensionService } from '../../../services/extensions/common/extensions';
export class TerminalService extends AbstractTerminalService implements ITerminalService { export class TerminalService extends AbstractTerminalService implements ITerminalService {
private _configHelper: TerminalConfigHelper; private _configHelper: TerminalConfigHelper;
...@@ -47,7 +48,8 @@ export class TerminalService extends AbstractTerminalService implements ITermina ...@@ -47,7 +48,8 @@ export class TerminalService extends AbstractTerminalService implements ITermina
@IInstantiationService private readonly _instantiationService: IInstantiationService, @IInstantiationService private readonly _instantiationService: IInstantiationService,
@IQuickOpenService private readonly _quickOpenService: IQuickOpenService, @IQuickOpenService private readonly _quickOpenService: IQuickOpenService,
@INotificationService private readonly _notificationService: INotificationService, @INotificationService private readonly _notificationService: INotificationService,
@IDialogService private readonly _dialogService: IDialogService @IDialogService private readonly _dialogService: IDialogService,
@IExtensionService private readonly _extensionService: IExtensionService
) { ) {
super(contextKeyService, panelService, partService, lifecycleService, storageService); super(contextKeyService, panelService, partService, lifecycleService, storageService);
...@@ -93,17 +95,15 @@ export class TerminalService extends AbstractTerminalService implements ITermina ...@@ -93,17 +95,15 @@ export class TerminalService extends AbstractTerminalService implements ITermina
return this._instantiationService.createInstance(TerminalInstance, terminalFocusContextKey, configHelper, undefined, shellLaunchConfig, true); return this._instantiationService.createInstance(TerminalInstance, terminalFocusContextKey, configHelper, undefined, shellLaunchConfig, true);
} }
public requestExtHostProcess(proxy: ITerminalProcessExtHostProxy): TPromise<void> { public requestExtHostProcess(proxy: ITerminalProcessExtHostProxy): void {
let i = 0; // Ensure extension host is ready before requesting a process
setTimeout(() => { this._extensionService.whenInstalledExtensionsRegistered().then(() => {
proxy.emitPid(-1); // TODO: MainThreadTerminalService is not ready at this point, fix this
proxy.emitTitle('test title'); setTimeout(() => {
proxy.emitData(`test ${i++}\r\n`); console.log('request');
}, 0); this._onInstanceRequestExtHostProcess.fire(proxy);
setInterval(() => { }, 100);
proxy.emitData(`test ${i++}\r\n`); });
}, 1000);
return TPromise.as(void 0);
} }
public focusFindWidget(): TPromise<void> { public focusFindWidget(): TPromise<void> {
......
...@@ -6,17 +6,19 @@ ...@@ -6,17 +6,19 @@
import { ITerminalChildProcess, IMessageToTerminalProcess, IMessageFromTerminalProcess } from 'vs/workbench/parts/terminal/node/terminal'; import { ITerminalChildProcess, IMessageToTerminalProcess, IMessageFromTerminalProcess } from 'vs/workbench/parts/terminal/node/terminal';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import { ITerminalService, ITerminalProcessExtHostProxy } from 'vs/workbench/parts/terminal/common/terminal'; import { ITerminalService, ITerminalProcessExtHostProxy } from 'vs/workbench/parts/terminal/common/terminal';
import { IDisposable } from '../../../../base/common/lifecycle';
export class TerminalProcessExtHostProxy extends EventEmitter implements ITerminalChildProcess, ITerminalProcessExtHostProxy { export class TerminalProcessExtHostProxy extends EventEmitter implements ITerminalChildProcess, ITerminalProcessExtHostProxy {
public connected: boolean; public connected: boolean;
constructor( constructor(
public terminalId: number,
@ITerminalService private _terminalService: ITerminalService @ITerminalService private _terminalService: ITerminalService
) { ) {
super(); super();
this._terminalService.requestExtHostProcess(this).then(() => { // TODO: Return TPromise<boolean> indicating success? Teardown if failure?
}); this._terminalService.requestExtHostProcess(this);
} }
public emitData(data: string): void { public emitData(data: string): void {
...@@ -30,7 +32,21 @@ export class TerminalProcessExtHostProxy extends EventEmitter implements ITermin ...@@ -30,7 +32,21 @@ export class TerminalProcessExtHostProxy extends EventEmitter implements ITermin
} }
public send(message: IMessageToTerminalProcess): boolean { public send(message: IMessageToTerminalProcess): boolean {
console.log('TerminalProcessExtHostBridge#send', arguments); console.log('TerminalProcessExtHostProxy#send');
if (message.event === 'input') {
console.log('emit input', message.data);
this.emit('input', message.data);
}
return true; return true;
} }
public onInput(listener: (data: string) => void): IDisposable {
console.log('TerminalProcessExtHostProxy#onInput', arguments);
// TODO: Dispose of me
this.on('input', data => {
console.log('TerminalProcessExtHostProxy#onInput - listener');
listener(data);
});
return null;
}
} }
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册