From cfd00529eb2c48958c4d83ef3343ea4655bea1e5 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 14 Jan 2018 17:19:31 -0800 Subject: [PATCH] Various fixes - Add buffers being retained on full reset (CIS) - Remove setup event, simplify - Only have one trim listener active at once - Disallow activate events if nothing changed (just in case) --- src/BufferSet.ts | 17 ++++++++++++++--- src/SelectionManager.ts | 37 +++++++++++++++---------------------- src/Terminal.ts | 3 ++- src/utils/TestUtils.test.ts | 2 +- 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/BufferSet.ts b/src/BufferSet.ts index e31d2278..da8c75f2 100644 --- a/src/BufferSet.ts +++ b/src/BufferSet.ts @@ -61,24 +61,35 @@ export class BufferSet extends EventEmitter implements IBufferSet { * Sets the normal Buffer of the BufferSet as its currently active Buffer */ public activateNormalBuffer(): void { + if (this._activeBuffer === this._normal) { + return; + } // The alt buffer should always be cleared when we switch to the normal // buffer. This frees up memory since the alt buffer should always be new // when activated. this._alt.clear(); - this._activeBuffer = this._normal; - this.emit('activate', this._normal); + this.emit('activate', { + activeBuffer: this._normal, + inactiveBuffer: this._alt + }); } /** * Sets the alt Buffer of the BufferSet as its currently active Buffer */ public activateAltBuffer(): void { + if (this._activeBuffer === this._alt) { + return; + } // Since the alt buffer is always cleared when the normal buffer is // activated, we want to fill it when switching to it. this._alt.fillViewportRows(); this._activeBuffer = this._alt; - this.emit('activate', this._alt); + this.emit('activate', { + activeBuffer: this._alt, + inactiveBuffer: this._normal + }); } /** diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 29003629..e625ab73 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -8,7 +8,7 @@ import * as Browser from './utils/Browser'; import { CharMeasure } from './utils/CharMeasure'; import { CircularList } from './utils/CircularList'; import { EventEmitter } from './EventEmitter'; -import { ITerminal, ICircularList, ISelectionManager, IBuffer } from './Interfaces'; +import { ITerminal, ICircularList, ISelectionManager, IBuffer, IListenerType } from './Interfaces'; import { SelectionModel } from './SelectionModel'; import { LineData, CharData } from './Types'; import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from './Buffer'; @@ -95,6 +95,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager private _mouseMoveListener: EventListener; private _mouseUpListener: EventListener; + private _trimListener: IListenerType; constructor( private _terminal: ITerminal, @@ -118,28 +119,10 @@ export class SelectionManager extends EventEmitter implements ISelectionManager private _initListeners(): void { this._mouseMoveListener = event => this._onMouseMove(event); this._mouseUpListener = event => this._onMouseUp(event); + this._trimListener = (amount: number) => this._onTrim(amount); - this._updateBufferSetHandlers(); - this._terminal.on('setup', () => { - this._onSetupHandler(); - }); - } - - private _onSetupHandler(): void { - this.clearSelection(); - this._updateBufferSetHandlers(); - } - - private _updateBufferSetHandlers(): void { - this._terminal.buffers.on('activate', (buffer: IBuffer) => { - this.clearSelection(); - }); - // Only adjust the selection on trim, shiftElements is rarely used (only in - // reverseIndex) and delete in a splice is only ever used when the same - // number of elements was just added. Given this is could actually be - // beneficial to leave the selection as is for these cases. - this._terminal.buffers.normal.lines.on('trim', (amount: number) => this._onTrim(amount)); - this._terminal.buffers.alt.lines.on('trim', (amount: number) => this._onTrim(amount)); + this._terminal.buffer.lines.on('trim', this._trimListener); + this._terminal.buffers.on('activate', e => this._onBufferActivate(e)); } /** @@ -556,6 +539,16 @@ export class SelectionManager extends EventEmitter implements ISelectionManager this._terminal.emit('selection'); } + private _onBufferActivate(e: {activeBuffer: IBuffer, inactiveBuffer: IBuffer}): void { + this.clearSelection(); + // Only adjust the selection on trim, shiftElements is rarely used (only in + // reverseIndex) and delete in a splice is only ever used when the same + // number of elements was just added. Given this is could actually be + // beneficial to leave the selection as is for these cases. + e.inactiveBuffer.lines.off('trim', this._trimListener); + e.activeBuffer.lines.on('trim', this._trimListener); + } + /** * Converts a viewport column to the character index on the buffer line, the * latter takes into account wide characters. diff --git a/src/Terminal.ts b/src/Terminal.ts index 11c2cf5e..02c74a3d 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -292,7 +292,6 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // Create the terminal's buffers and set the current buffer this.buffers = new BufferSet(this); - this.emit('setup'); } /** @@ -2077,9 +2076,11 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT this.options.cols = this.cols; const customKeyEventHandler = this.customKeyEventHandler; const inputHandler = this.inputHandler; + const buffers = this.buffers; this.setup(); this.customKeyEventHandler = customKeyEventHandler; this.inputHandler = inputHandler; + this.buffers = buffers; this.refresh(0, this.rows - 1); this.viewport.syncScrollArea(); } diff --git a/src/utils/TestUtils.test.ts b/src/utils/TestUtils.test.ts index 54c52078..80e25277 100644 --- a/src/utils/TestUtils.test.ts +++ b/src/utils/TestUtils.test.ts @@ -37,7 +37,7 @@ export class MockTerminal implements ITerminal { throw new Error('Method not implemented.'); } on(event: string, callback: () => void): void { - /* Simply do nothing */ + throw new Error('Method not implemented.'); } off(type: string, listener: IListenerType): void { throw new Error('Method not implemented.');