diff --git a/src/vs/workbench/api/electron-browser/mainThreadTerminalService.ts b/src/vs/workbench/api/electron-browser/mainThreadTerminalService.ts index 242091da9b1..ccf129ce117 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadTerminalService.ts @@ -178,7 +178,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape }; this._proxy.$createProcess(request.proxy.terminalId, shellLaunchConfigDto, request.cols, request.rows); request.proxy.onInput(data => this._proxy.$acceptProcessInput(request.proxy.terminalId, data)); - request.proxy.onResize((cols, rows) => this._proxy.$acceptProcessResize(request.proxy.terminalId, cols, rows)); + request.proxy.onResize(dimensions => this._proxy.$acceptProcessResize(request.proxy.terminalId, dimensions.cols, dimensions.rows)); request.proxy.onShutdown(() => this._proxy.$acceptProcessShutdown(request.proxy.terminalId)); } diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 956f724057e..282811368f9 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -5,17 +5,16 @@ 'use strict'; import * as vscode from 'vscode'; -import * as cp from 'child_process'; import * as os from 'os'; import * as platform from 'vs/base/common/platform'; import * as terminalEnvironment from 'vs/workbench/parts/terminal/node/terminalEnvironment'; import Uri from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto } from 'vs/workbench/api/node/extHost.protocol'; -import { IMessageFromTerminalProcess } from 'vs/workbench/parts/terminal/node/terminal'; import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration'; import { ILogService } from 'vs/platform/log/common/log'; import { EXT_HOST_CREATION_DELAY } from 'vs/workbench/parts/terminal/common/terminal'; +import { TerminalProcess } from 'vs/workbench/parts/terminal/node/terminalProcess'; const RENDERER_NO_PROCESS_ID = -1; @@ -226,7 +225,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { private _proxy: MainThreadTerminalServiceShape; private _activeTerminal: ExtHostTerminal; private _terminals: ExtHostTerminal[] = []; - private _terminalProcesses: { [id: number]: cp.ChildProcess } = {}; + private _terminalProcesses: { [id: number]: TerminalProcess } = {}; private _terminalRenderers: ExtHostTerminalRenderer[] = []; public get activeTerminal(): ExtHostTerminal { return this._activeTerminal; } @@ -397,27 +396,29 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { // Fork the process and listen for messages this._logService.debug(`Terminal process launching on ext host`, options); - this._terminalProcesses[id] = cp.fork(Uri.parse(require.toUrl('bootstrap')).fsPath, ['--type=terminal'], options); - this._terminalProcesses[id].on('message', (message: IMessageFromTerminalProcess) => { - switch (message.type) { - case 'pid': this._proxy.$sendProcessPid(id, message.content); break; - case 'title': this._proxy.$sendProcessTitle(id, message.content); break; - case 'data': this._proxy.$sendProcessData(id, message.content); break; - } - }); - this._terminalProcesses[id].on('exit', (exitCode) => this._onProcessExit(id, exitCode)); + this._terminalProcesses[id] = new TerminalProcess(shellLaunchConfig.executable, shellLaunchConfig.args, cwd, cols, rows); + // this._terminalProcesses[id].on + // this._terminalProcesses[id].on('message', (message: IMessageFromTerminalProcess) => { + // switch (message.type) { + // }); + this._terminalProcesses[id].onProcessIdReady(pid => this._proxy.$sendProcessPid(id, pid)); + this._terminalProcesses[id].onProcessTitleChanged(title => this._proxy.$sendProcessTitle(id, title)); + this._terminalProcesses[id].onProcessData(data => this._proxy.$sendProcessData(id, data)); + this._terminalProcesses[id].onProcessExit((exitCode) => this._onProcessExit(id, exitCode)); } public $acceptProcessInput(id: number, data: string): void { - if (this._terminalProcesses[id].connected) { - this._terminalProcesses[id].send({ event: 'input', data }); + if (this._terminalProcesses[id].isConnected) { + this._terminalProcesses[id].input(data); + // this._terminalProcesses[id].send({ event: 'input', data }); } } public $acceptProcessResize(id: number, cols: number, rows: number): void { - if (this._terminalProcesses[id].connected) { + if (this._terminalProcesses[id].isConnected) { try { - this._terminalProcesses[id].send({ event: 'resize', cols, rows }); + this._terminalProcesses[id].resize(cols, rows); + // this._terminalProcesses[id].send({ event: 'resize', cols, rows }); } catch (error) { // We tried to write to a closed pipe / channel. if (error.code !== 'EPIPE' && error.code !== 'ERR_IPC_CHANNEL_CLOSED') { @@ -428,16 +429,17 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { } public $acceptProcessShutdown(id: number): void { - if (this._terminalProcesses[id].connected) { - this._terminalProcesses[id].send({ event: 'shutdown' }); + if (this._terminalProcesses[id].isConnected) { + this._terminalProcesses[id].shutdown(); + // this._terminalProcesses[id].send({ event: 'shutdown' }); } } private _onProcessExit(id: number, exitCode: number): void { // Remove listeners - const process = this._terminalProcesses[id]; - process.removeAllListeners('message'); - process.removeAllListeners('exit'); + // const process = this._terminalProcesses[id]; + // process.removeAllListeners('message'); + // process.removeAllListeners('exit'); // Remove process reference delete this._terminalProcesses[id]; diff --git a/src/vs/workbench/parts/terminal/common/terminal.ts b/src/vs/workbench/parts/terminal/common/terminal.ts index 81613ecef7b..ffcd27e8f46 100644 --- a/src/vs/workbench/parts/terminal/common/terminal.ts +++ b/src/vs/workbench/parts/terminal/common/terminal.ts @@ -596,9 +596,9 @@ export interface ITerminalProcessExtHostProxy extends IDisposable { emitPid(pid: number): void; emitExit(exitCode: number): void; - onInput(listener: (data: string) => void): void; - onResize(listener: (cols: number, rows: number) => void): void; - onShutdown(listener: () => void): void; + onInput: Event; + onResize: Event<{ cols: number, rows: number }>; + onShutdown: Event; } export interface ITerminalProcessExtHostRequest { diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalProcessManager.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalProcessManager.ts index 1baae6f64c2..6cb1d68cb0c 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalProcessManager.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalProcessManager.ts @@ -15,8 +15,8 @@ import { Emitter, Event } from 'vs/base/common/event'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; -// import { ITerminalChildProcess, IMessageFromTerminalProcess } from 'vs/workbench/parts/terminal/node/terminal'; -// import { TerminalProcessExtHostProxy } from 'vs/workbench/parts/terminal/node/terminalProcessExtHostProxy'; +import { ITerminalChildProcess } from 'vs/workbench/parts/terminal/node/terminal'; +import { TerminalProcessExtHostProxy } from 'vs/workbench/parts/terminal/node/terminalProcessExtHostProxy'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TerminalProcess } from 'vs/workbench/parts/terminal/node/terminalProcess'; @@ -37,7 +37,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { public shellProcessId: number; public initialCwd: string; - private _process: TerminalProcess; + private _process: ITerminalChildProcess; private _preLaunchInputQueue: string[] = []; private _disposables: IDisposable[] = []; @@ -59,7 +59,6 @@ export class TerminalProcessManager implements ITerminalProcessManager { @IInstantiationService private readonly _instantiationService: IInstantiationService, @ILogService private _logService: ILogService ) { - console.log(this._terminalId, this._instantiationService); this.ptyProcessReady = new TPromise(c => { this.onProcessReady(() => { this._logService.debug(`Terminal process ready (shellProcessId: ${this.shellProcessId})`); @@ -93,42 +92,42 @@ export class TerminalProcessManager implements ITerminalProcessManager { cols: number, rows: number ): void { - // const extensionHostOwned = (this._configHelper.config).extHostProcess; - // if (extensionHostOwned) { - // this._process = this._instantiationService.createInstance(TerminalProcessExtHostProxy, this._terminalId, shellLaunchConfig, cols, rows); - // } else { - const locale = this._configHelper.config.setLocaleVariables ? platform.locale : undefined; - if (!shellLaunchConfig.executable) { - this._configHelper.mergeDefaultShellPathAndArgs(shellLaunchConfig); + const extensionHostOwned = (this._configHelper.config).extHostProcess; + if (extensionHostOwned) { + this._process = this._instantiationService.createInstance(TerminalProcessExtHostProxy, this._terminalId, shellLaunchConfig, cols, rows); + } else { + const locale = this._configHelper.config.setLocaleVariables ? platform.locale : undefined; + if (!shellLaunchConfig.executable) { + this._configHelper.mergeDefaultShellPathAndArgs(shellLaunchConfig); + } + + const lastActiveWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot('file'); + this.initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, lastActiveWorkspaceRootUri, this._configHelper); + + // Resolve env vars from config and shell + const lastActiveWorkspaceRoot = this._workspaceContextService.getWorkspaceFolder(lastActiveWorkspaceRootUri); + 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; + + // Merge process env with the env from config + const parentEnv = { ...process.env }; + terminalEnvironment.mergeEnvironments(parentEnv, envFromConfig); + + // Continue env initialization, merging in the env from the launch + // config and adding keys that are needed to create the process + const env = terminalEnvironment.createTerminalEnv(parentEnv, shellLaunchConfig, this.initialCwd, locale, cols, rows); + const cwd = Uri.parse(require.toUrl('../node')).fsPath; + const options = { env, cwd }; + this._logService.debug(`Terminal process launching`, options); + + // this._process = cp.fork(Uri.parse(require.toUrl('bootstrap')).fsPath, ['--type=terminal'], options); + this._process = new TerminalProcess(env['PTYSHELL'], [], env['PTYCWD'], cols, rows); } - - const lastActiveWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot('file'); - this.initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, lastActiveWorkspaceRootUri, this._configHelper); - - // Resolve env vars from config and shell - const lastActiveWorkspaceRoot = this._workspaceContextService.getWorkspaceFolder(lastActiveWorkspaceRootUri); - 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; - - // Merge process env with the env from config - const parentEnv = { ...process.env }; - terminalEnvironment.mergeEnvironments(parentEnv, envFromConfig); - - // Continue env initialization, merging in the env from the launch - // config and adding keys that are needed to create the process - const env = terminalEnvironment.createTerminalEnv(parentEnv, shellLaunchConfig, this.initialCwd, locale, cols, rows); - const cwd = Uri.parse(require.toUrl('../node')).fsPath; - const options = { env, cwd }; - this._logService.debug(`Terminal process launching`, options); - - // this._process = cp.fork(Uri.parse(require.toUrl('bootstrap')).fsPath, ['--type=terminal'], options); - this._process = new TerminalProcess(env['PTYSHELL'], [], env['PTYCWD'], cols, rows); - // } this.processState = ProcessState.LAUNCHING; - this._process.onData(data => { + this._process.onProcessData(data => { this._onProcessData.fire(data); }); @@ -143,8 +142,8 @@ export class TerminalProcessManager implements ITerminalProcessManager { } }); - this._process.onTitleChanged(title => this._onProcessTitle.fire(title)); - this._process.onExit(exitCode => this._onExit(exitCode)); + this._process.onProcessTitleChanged(title => this._onProcessTitle.fire(title)); + this._process.onProcessExit(exitCode => this._onExit(exitCode)); // this._process.on('message', message => this._onMessage(message)); // this._process.on('exit', exitCode => this._onExit(exitCode)); diff --git a/src/vs/workbench/parts/terminal/node/terminal.ts b/src/vs/workbench/parts/terminal/node/terminal.ts index 8cb9bc9dddd..d85830b8a04 100644 --- a/src/vs/workbench/parts/terminal/node/terminal.ts +++ b/src/vs/workbench/parts/terminal/node/terminal.ts @@ -7,30 +7,24 @@ import * as os from 'os'; import * as platform from 'vs/base/common/platform'; import * as processes from 'vs/base/node/processes'; import { readFile, fileExists } from 'vs/base/node/pfs'; - -export interface IMessageFromTerminalProcess { - type: 'pid' | 'data' | 'title'; - content: number | string; -} - -export interface IMessageToTerminalProcess { - event: 'resize' | 'input' | 'shutdown'; - data?: string; - cols?: number; - rows?: number; -} +import { Event } from 'vs/base/common/event'; /** * An interface representing a raw terminal child process, this is a subset of the * child_process.ChildProcess node.js interface. */ export interface ITerminalChildProcess { - readonly connected: boolean; + // TODO: Remove connected and references to it + readonly isConnected: boolean; - send(message: IMessageToTerminalProcess): boolean; + onProcessData: Event; + onProcessExit: Event; + onProcessIdReady: Event; + onProcessTitleChanged: Event; - on(event: 'exit', listener: (code: number) => void): this; - on(event: 'message', listener: (message: IMessageFromTerminalProcess) => void): this; + shutdown(): void; + input(data: string): void; + resize(cols: number, rows: number): void; } let _TERMINAL_DEFAULT_SHELL_UNIX_LIKE: string = null; diff --git a/src/vs/workbench/parts/terminal/node/terminalEnvironment.ts b/src/vs/workbench/parts/terminal/node/terminalEnvironment.ts index 8e2bca6dadd..e54909e939a 100644 --- a/src/vs/workbench/parts/terminal/node/terminalEnvironment.ts +++ b/src/vs/workbench/parts/terminal/node/terminalEnvironment.ts @@ -58,23 +58,23 @@ export function createTerminalEnv(parentEnv: IStringDictionary, shell: I mergeEnvironments(env, shell.env); } - env['PTYPID'] = process.pid.toString(); - env['PTYSHELL'] = shell.executable; + // env['PTYPID'] = process.pid.toString(); + // env['PTYSHELL'] = shell.executable; env['TERM_PROGRAM'] = 'vscode'; env['TERM_PROGRAM_VERSION'] = pkg.version; - if (shell.args) { - if (typeof shell.args === 'string') { - env[`PTYSHELLCMDLINE`] = shell.args; - } else { - shell.args.forEach((arg, i) => env[`PTYSHELLARG${i}`] = arg); - } - } - env['PTYCWD'] = cwd; + // if (shell.args) { + // if (typeof shell.args === 'string') { + // env[`PTYSHELLCMDLINE`] = shell.args; + // } else { + // shell.args.forEach((arg, i) => env[`PTYSHELLARG${i}`] = arg); + // } + // } + // env['PTYCWD'] = cwd; env['LANG'] = _getLangEnvVariable(locale); - if (cols && rows) { - env['PTYCOLS'] = cols.toString(); - env['PTYROWS'] = rows.toString(); - } + // if (cols && rows) { + // env['PTYCOLS'] = cols.toString(); + // env['PTYROWS'] = rows.toString(); + // } env['AMD_ENTRYPOINT'] = 'vs/workbench/parts/terminal/node/terminalProcess'; return env; } diff --git a/src/vs/workbench/parts/terminal/node/terminalProcess.ts b/src/vs/workbench/parts/terminal/node/terminalProcess.ts index 5404e59b07d..050de680e29 100644 --- a/src/vs/workbench/parts/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/parts/terminal/node/terminalProcess.ts @@ -8,21 +8,22 @@ import * as path from 'path'; import * as pty from 'node-pty'; import { Event, Emitter } from 'vs/base/common/event'; import { IProcessEnvironment } from 'vs/base/common/platform'; +import { ITerminalChildProcess } from 'vs/workbench/parts/terminal/node/terminal'; -export class TerminalProcess { +export class TerminalProcess implements ITerminalChildProcess { private _exitCode: number; private _closeTimeout: number; private _ptyProcess: pty.IPty; private _currentTitle: string = ''; - private readonly _onData: Emitter = new Emitter(); - public get onData(): Event { return this._onData.event; } - private readonly _onExit: Emitter = new Emitter(); - public get onExit(): Event { return this._onExit.event; } + private readonly _onProcessData: Emitter = new Emitter(); + public get onProcessData(): Event { return this._onProcessData.event; } + private readonly _onProcessExit: Emitter = new Emitter(); + public get onProcessExit(): Event { return this._onProcessExit.event; } private readonly _onProcessIdReady: Emitter = new Emitter(); public get onProcessIdReady(): Event { return this._onProcessIdReady.event; } - private readonly _onTitleChanged: Emitter = new Emitter(); - public get onTitleChanged(): Event { return this._onTitleChanged.event; } + private readonly _onProcessTitleChanged: Emitter = new Emitter(); + public get onProcessTitleChanged(): Event { return this._onProcessTitleChanged.event; } constructor(shell: string, args: string | string[], cwd: string, cols: number, rows: number) { // The pty process needs to be run in its own child process to get around maxing out CPU on Mac, @@ -46,7 +47,7 @@ export class TerminalProcess { this._ptyProcess = pty.spawn(shell, args, options); this._ptyProcess.on('data', (data) => { - this._onData.fire(data); + this._onProcessData.fire(data); if (this._closeTimeout) { clearTimeout(this._closeTimeout); this._queueProcessExit(); @@ -112,7 +113,7 @@ export class TerminalProcess { // TODO: Dispose correctly this._closeTimeout = setTimeout(() => { this._ptyProcess.kill(); - this._onExit.fire(this._exitCode); + this._onProcessExit.fire(this._exitCode); }, 250); } @@ -121,7 +122,7 @@ export class TerminalProcess { } private _sendProcessTitle(): void { this._currentTitle = this._ptyProcess.process; - this._onTitleChanged.fire(this._currentTitle); + this._onProcessTitleChanged.fire(this._currentTitle); } public shutdown(): void { diff --git a/src/vs/workbench/parts/terminal/node/terminalProcessExtHostProxy.ts b/src/vs/workbench/parts/terminal/node/terminalProcessExtHostProxy.ts index 9c842fbbfa8..422e7ae45c5 100644 --- a/src/vs/workbench/parts/terminal/node/terminalProcessExtHostProxy.ts +++ b/src/vs/workbench/parts/terminal/node/terminalProcessExtHostProxy.ts @@ -3,17 +3,33 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ITerminalChildProcess, IMessageToTerminalProcess, IMessageFromTerminalProcess } from 'vs/workbench/parts/terminal/node/terminal'; -import { EventEmitter } from 'events'; +import { ITerminalChildProcess } from 'vs/workbench/parts/terminal/node/terminal'; +import { Event, Emitter } from 'vs/base/common/event'; import { ITerminalService, ITerminalProcessExtHostProxy, IShellLaunchConfig } from 'vs/workbench/parts/terminal/common/terminal'; -import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable } from 'vs/base/common/lifecycle'; -export class TerminalProcessExtHostProxy extends EventEmitter implements ITerminalChildProcess, ITerminalProcessExtHostProxy { +export class TerminalProcessExtHostProxy implements ITerminalChildProcess, ITerminalProcessExtHostProxy { // For ext host processes connected checks happen on the ext host - public connected: boolean = true; + public isConnected: boolean = true; private _disposables: IDisposable[] = []; + private readonly _onProcessData: Emitter = new Emitter(); + public get onProcessData(): Event { return this._onProcessData.event; } + private readonly _onProcessExit: Emitter = new Emitter(); + public get onProcessExit(): Event { return this._onProcessExit.event; } + private readonly _onProcessIdReady: Emitter = new Emitter(); + public get onProcessIdReady(): Event { return this._onProcessIdReady.event; } + private readonly _onProcessTitleChanged: Emitter = new Emitter(); + public get onProcessTitleChanged(): Event { return this._onProcessTitleChanged.event; } + + private readonly _onInput: Emitter = new Emitter(); + public get onInput(): Event { return this._onInput.event; } + private readonly _onResize: Emitter<{ cols: number, rows: number }> = new Emitter<{ cols: number, rows: number }>(); + public get onResize(): Event<{ cols: number, rows: number }> { return this._onResize.event; } + private readonly _onShutdown: Emitter = new Emitter(); + public get onShutdown(): Event { return this._onShutdown.event; } + constructor( public terminalId: number, shellLaunchConfig: IShellLaunchConfig, @@ -21,8 +37,6 @@ export class TerminalProcessExtHostProxy extends EventEmitter implements ITermin rows: number, @ITerminalService private _terminalService: ITerminalService ) { - super(); - // TODO: Return TPromise indicating success? Teardown if failure? this._terminalService.requestExtHostProcess(this, shellLaunchConfig, cols, rows); } @@ -33,46 +47,59 @@ export class TerminalProcessExtHostProxy extends EventEmitter implements ITermin } public emitData(data: string): void { - this.emit('message', { type: 'data', content: data } as IMessageFromTerminalProcess); + this._onProcessData.fire(data); } public emitTitle(title: string): void { - this.emit('message', { type: 'title', content: title } as IMessageFromTerminalProcess); + this._onProcessTitleChanged.fire(title); } public emitPid(pid: number): void { - this.emit('message', { type: 'pid', content: pid } as IMessageFromTerminalProcess); + this._onProcessIdReady.fire(pid); } public emitExit(exitCode: number): void { - this.emit('exit', exitCode); + this._onProcessExit.fire(exitCode); this.dispose(); } - public send(message: IMessageToTerminalProcess): boolean { - switch (message.event) { - case 'input': this.emit('input', message.data); break; - case 'resize': this.emit('resize', message.cols, message.rows); break; - case 'shutdown': this.emit('shutdown'); break; - } - return true; + // public send(message: IMessageToTerminalProcess): boolean { + // switch (message.event) { + // case 'input': this.emit('input', message.data); break; + // case 'resize': this.emit('resize', message.cols, message.rows); break; + // case 'shutdown': this.emit('shutdown'); break; + // } + // return true; + // } + + public shutdown(): void { + this._onShutdown.fire(); } - public onInput(listener: (data: string) => void): void { - const outerListener = (data) => listener(data); - this.on('input', outerListener); - this._disposables.push(toDisposable(() => this.removeListener('input', outerListener))); + public input(data: string): void { + this._onInput.fire(data); } - public onResize(listener: (cols: number, rows: number) => void): void { - const outerListener = (cols, rows) => listener(cols, rows); - this.on('resize', outerListener); - this._disposables.push(toDisposable(() => this.removeListener('resize', outerListener))); + public resize(cols: number, rows: number): void { + this._onResize.fire({ cols, rows }); } - public onShutdown(listener: () => void): void { - const outerListener = () => listener(); - this.on('shutdown', outerListener); - this._disposables.push(toDisposable(() => this.removeListener('shutdown', outerListener))); - } + + // public onInput(listener: (data: string) => void): void { + // const outerListener = (data) => listener(data); + // this.on('input', outerListener); + // this._disposables.push(toDisposable(() => this.removeListener('input', outerListener))); + // } + + // public onResize(listener: (cols: number, rows: number) => void): void { + // const outerListener = (cols, rows) => listener(cols, rows); + // this.on('resize', outerListener); + // this._disposables.push(toDisposable(() => this.removeListener('resize', outerListener))); + // } + + // public onShutdown(listener: () => void): void { + // const outerListener = () => listener(); + // this.on('shutdown', outerListener); + // this._disposables.push(toDisposable(() => this.removeListener('shutdown', outerListener))); + // } } \ No newline at end of file