Skip to content

Commit

Permalink
Send last line terminal data when process exits
Browse files Browse the repository at this point in the history
Part of #32042
Part of #29840
  • Loading branch information
Tyriar authored and egamma committed Oct 31, 2017
1 parent dc01042 commit 9b656f3
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 21 deletions.
7 changes: 4 additions & 3 deletions src/vs/workbench/parts/terminal/common/terminal.ts
Expand Up @@ -364,9 +364,10 @@ export interface ITerminalInstance {
*
* @param listener The listener function which takes new line strings added to the terminal,
* excluding ANSI escape sequences. The line event will fire when an LF character is added to
* the terminal (ie. the line is not wrapped), note that this means taht the line data will
* never fire for the last line, until the line is ended with a LF character. The lineData
* string will contain the fully wrapped line, not containing any LF/CR characters.
* the terminal (ie. the line is not wrapped). Note that this means that the line data will
* not fire for the last line, until either the line is ended with a LF character of the process
* is exited. The lineData string will contain the fully wrapped line, not containing any LF/CR
* characters.
*/
onLineData(listener: (lineData: string) => void): IDisposable;

Expand Down
Expand Up @@ -107,6 +107,7 @@ export class TerminalInstance implements ITerminalInstance {
private _preLaunchInputQueue: string;
private _initialCwd: string;
private _windowsShellHelper: WindowsShellHelper;
private _onLineDataListeners: ((lineData: string) => void)[];

private _widgetManager: TerminalWidgetManager;
private _linkHandler: TerminalLinkHandler;
Expand Down Expand Up @@ -140,6 +141,7 @@ export class TerminalInstance implements ITerminalInstance {
this._instanceDisposables = [];
this._processDisposables = [];
this._skipTerminalCommands = [];
this._onLineDataListeners = [];
this._isExiting = false;
this._hadFocusOnExit = false;
this._processState = ProcessState.UNINITIALIZED;
Expand Down Expand Up @@ -272,6 +274,7 @@ export class TerminalInstance implements ITerminalInstance {
if (this._shellLaunchConfig.initialText) {
this._xterm.writeln(this._shellLaunchConfig.initialText);
}
this._xterm.on('lineFeed', () => this._onLineFeed());
this._process.on('message', (message) => this._sendPtyDataToXterm(message));
this._xterm.on('data', (data) => {
if (this._processId) {
Expand Down Expand Up @@ -451,6 +454,8 @@ export class TerminalInstance implements ITerminalInstance {
this._wrapperElement = null;
}
if (this._xterm) {
const buffer = (<any>this._xterm.buffer);
this._sendLineData(buffer, buffer.ybase + buffer.y);
this._xterm.destroy();
this._xterm = null;
}
Expand Down Expand Up @@ -828,31 +833,36 @@ export class TerminalInstance implements ITerminalInstance {
}

public onLineData(listener: (lineData: string) => void): lifecycle.IDisposable {
if (!this._xterm) {
throw new Error('xterm must be initialized');
}
const lineFeedListener = () => {
const buffer = (<any>this._xterm.buffer);
const newLine = buffer.lines.get(buffer.ybase + buffer.y);
if (!newLine.isWrapped) {
let i = buffer.ybase + buffer.y - 1;
let lineData = buffer.translateBufferLineToString(i, true);
while (i >= 0 && buffer.lines.get(i--).isWrapped) {
lineData = buffer.translateBufferLineToString(i, true) + lineData;
}
listener(lineData);
}
};
this._xterm.on('lineFeed', lineFeedListener);
this._onLineDataListeners.push(listener);
return {
dispose: () => {
if (this._xterm) {
this._xterm.off('lineFeed', lineFeedListener);
const i = this._onLineDataListeners.indexOf(listener);
if (i >= 0) {
this._onLineDataListeners.splice(i, 1);
}
}
};
}

private _onLineFeed(): void {
if (this._onLineDataListeners.length === 0) {
return;
}
const buffer = (<any>this._xterm.buffer);
const newLine = buffer.lines.get(buffer.ybase + buffer.y);
if (!newLine.isWrapped) {
this._sendLineData(buffer, buffer.ybase + buffer.y - 1);
}
}

private _sendLineData(buffer: any, lineIndex: number): void {
let lineData = buffer.translateBufferLineToString(lineIndex, true);
while (lineIndex >= 0 && buffer.lines.get(lineIndex--).isWrapped) {
lineData = buffer.translateBufferLineToString(lineIndex, true) + lineData;
}
this._onLineDataListeners.forEach(listener => listener(lineData));
}

public onExit(listener: (exitCode: number) => void): lifecycle.IDisposable {
if (this._process) {
this._process.on('exit', listener);
Expand Down

0 comments on commit 9b656f3

Please sign in to comment.