diff --git a/src/vs/workbench/parts/terminal/common/terminal.ts b/src/vs/workbench/parts/terminal/common/terminal.ts index aaff277951ad1cb92fa53d7f9fc7463c76b9e341..17b62d064f0629b152809730869c679f2a135ceb 100644 --- a/src/vs/workbench/parts/terminal/common/terminal.ts +++ b/src/vs/workbench/parts/terminal/common/terminal.ts @@ -265,4 +265,11 @@ export interface ITerminalInstance { * null means the process was killed as a result of the ITerminalInstance being disposed. */ onExit(listener: (exitCode: number) => void): void; + + /** + * Immediately kills the terminal's current pty process and launches a new one to replace it. + * + * @param shell The new launch configuration. + */ + reuseTerminal(shell: IShellLaunchConfig): void; } diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index f54dc1069caead9688f0943eacd10cbc449c8fbe..d8ae919075b750e66c3037e5a9e072928f9faaf5 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -110,14 +110,7 @@ export class TerminalInstance implements ITerminalInstance { }); this._xterm.open(this._xtermElement); - this._process.on('message', (message) => { - if (!this._xterm) { - return; - } - if (message.type === 'data') { - this._xterm.write(message.content); - } - }); + this._process.on('message', (message) => this._sendPtyDataToXterm(message)); this._xterm.on('data', (data) => { this._process.send({ event: 'input', @@ -371,6 +364,15 @@ export class TerminalInstance implements ITerminalInstance { }, LAUNCHING_DURATION); } + private _sendPtyDataToXterm(message: { type: string, content: string }): void { + if (!this._xterm) { + return; + } + if (message.type === 'data') { + this._xterm.write(message.content); + } + } + private _onPtyProcessExit(exitCode: number): void { // Prevent dispose functions being triggered multiple times if (this._isExiting) { @@ -418,6 +420,26 @@ export class TerminalInstance implements ITerminalInstance { } } + public reuseTerminal(shell: IShellLaunchConfig): void { + if (this._process) { + this._process.removeAllListeners('exit'); + if (this._process.connected) { + this._process.kill(); + } + this._process = null; + } + // Ensure new processes' output starts at start of new line + this._xterm.write('\n\x1b[G'); + this._createProcess(this._contextService.getWorkspace(), shell.name, shell); + this._process.on('message', (message) => this._sendPtyDataToXterm(message)); + // TODO: Get rid of wait for any key listeners and any other listeners that are no longer valid + if (this._isExiting && this._shellLaunchConfig.waitOnExit) { + this._xterm.setOption('disableStdin', false); + } + // Set the new shell launch config + this._shellLaunchConfig = shell; + } + // TODO: This should be private/protected // TODO: locale should not be optional public static createTerminalEnv(parentEnv: IStringDictionary, shell: IShellLaunchConfig, cwd: string, locale?: string): IStringDictionary {