diff --git a/src/Buffer.ts b/src/Buffer.ts index 4f81025fe5..4c73006391 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -82,10 +82,10 @@ export class Buffer implements IBuffer { this.ybase = 0; this.y = 0; this.x = 0; - this.tabs = {}; this._lines = new CircularList(this._getCorrectBufferLength(this._terminal.rows)); this.scrollTop = 0; this.scrollBottom = this._terminal.rows - 1; + this.setupTabStops(); } /** @@ -233,4 +233,47 @@ export class Buffer implements IBuffer { return lineString.substring(widthAdjustedStartCol, finalEndCol); } + + /** + * Setup the tab stops. + * @param i The index to start setting up tab stops from. + */ + public setupTabStops(i?: number): void { + if (i != null) { + if (!this.tabs[i]) { + i = this.prevStop(i); + } + } else { + this.tabs = {}; + i = 0; + } + + for (; i < this._terminal.cols; i += this._terminal.options.tabStopWidth) { + this.tabs[i] = true; + } + } + + /** + * Move the cursor to the previous tab stop from the given position (default is current). + * @param x The position to move the cursor to the previous tab stop. + */ + public prevStop(x?: number): number { + if (x == null) { + x = this.x; + } + while (!this.tabs[--x] && x > 0); + return x >= this._terminal.cols ? this._terminal.cols - 1 : x < 0 ? 0 : x; + } + + /** + * Move the cursor one tab stop forward from the given position (default is current). + * @param x The position to move the cursor one tab stop forward. + */ + public nextStop(x?: number): number { + if (x == null) { + x = this.x; + } + while (!this.tabs[++x] && x < this._terminal.cols); + return x >= this._terminal.cols ? this._terminal.cols - 1 : x < 0 ? 0 : x; + } } diff --git a/src/BufferSet.ts b/src/BufferSet.ts index d37a650f94..64b364e92f 100644 --- a/src/BufferSet.ts +++ b/src/BufferSet.ts @@ -28,6 +28,8 @@ export class BufferSet extends EventEmitter implements IBufferSet { // See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer this._alt = new Buffer(this._terminal, false); this._activeBuffer = this._normal; + + this.setupTabStops(); } /** @@ -87,4 +89,13 @@ export class BufferSet extends EventEmitter implements IBufferSet { this._normal.resize(newCols, newRows); this._alt.resize(newCols, newRows); } + + /** + * Setup the tab stops. + * @param i The index to start setting up tab stops from. + */ + public setupTabStops(i?: number): void { + this._normal.setupTabStops(i); + this._alt.setupTabStops(i); + } } diff --git a/src/InputHandler.ts b/src/InputHandler.ts index f2d9775113..abfdfa0e6b 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -157,7 +157,7 @@ export class InputHandler implements IInputHandler { * Horizontal Tab (HT) (Ctrl-I). */ public tab(): void { - this._terminal.buffer.x = this._terminal.nextStop(); + this._terminal.buffer.x = this._terminal.buffer.nextStop(); } /** @@ -349,7 +349,7 @@ export class InputHandler implements IInputHandler { public cursorForwardTab(params: number[]): void { let param = params[0] || 1; while (param--) { - this._terminal.buffer.x = this._terminal.nextStop(); + this._terminal.buffer.x = this._terminal.buffer.nextStop(); } } @@ -548,7 +548,7 @@ export class InputHandler implements IInputHandler { public cursorBackwardTab(params: number[]): void { let param = params[0] || 1; while (param--) { - this._terminal.buffer.x = this._terminal.prevStop(); + this._terminal.buffer.x = this._terminal.buffer.prevStop(); } } diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 943003aec3..fb66f4d7cf 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -92,14 +92,12 @@ export interface IInputHandlingTerminal extends IEventEmitter { convertEol: boolean; updateRange(y: number): void; scroll(isWrapped?: boolean): void; - nextStop(x?: number): number; setgLevel(g: number): void; eraseAttr(): number; eraseRight(x: number, y: number): void; eraseLine(y: number): void; eraseLeft(x: number, y: number): void; blankLine(cur?: boolean, isWrapped?: boolean): LineData; - prevStop(x?: number): number; is(term: string): boolean; send(data: string): void; setgCharset(g: number, charset: Charset): void; @@ -146,6 +144,8 @@ export interface IBuffer { savedY: number; savedX: number; translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol?: number, endCol?: number): string; + nextStop(x?: number): number; + prevStop(x?: number): number; } export interface IBufferSet { diff --git a/src/Terminal.ts b/src/Terminal.ts index ea3800d0c5..827273ff52 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -392,8 +392,6 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT if (this.selectionManager) { this.selectionManager.setBuffer(this.buffer); } - - this.setupStops(); } /** @@ -486,7 +484,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT this.buffers.resize(this.cols, this.rows); this.viewport.syncScrollArea(); break; - case 'tabStopWidth': this.setupStops(); break; + case 'tabStopWidth': this.buffers.setupTabStops(); break; case 'bellSound': case 'bellStyle': this.syncBellSound(); break; } @@ -1938,7 +1936,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT this.cols = x; this.rows = y; - this.setupStops(this.cols); + this.buffers.setupTabStops(this.cols); this.charMeasure.measure(); @@ -1971,45 +1969,6 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT this.refreshEnd = this.rows - 1; } - /** - * Setup the tab stops. - * @param {number} i - */ - public setupStops(i?: number): void { - if (i != null) { - if (!this.buffer.tabs[i]) { - i = this.prevStop(i); - } - } else { - this.buffer.tabs = {}; - i = 0; - } - - for (; i < this.cols; i += this.getOption('tabStopWidth')) { - this.buffer.tabs[i] = true; - } - } - - /** - * Move the cursor to the previous tab stop from the given position (default is current). - * @param {number} x The position to move the cursor to the previous tab stop. - */ - public prevStop(x?: number): number { - if (x == null) x = this.buffer.x; - while (!this.buffer.tabs[--x] && x > 0); - return x >= this.cols ? this.cols - 1 : x < 0 ? 0 : x; - } - - /** - * Move the cursor one tab stop forward from the given position (default is current). - * @param {number} x The position to move the cursor one tab stop forward. - */ - public nextStop(x?: number): number { - if (x == null) x = this.buffer.x; - while (!this.buffer.tabs[++x] && x < this.cols); - return x >= this.cols ? this.cols - 1 : x < 0 ? 0 : x; - } - /** * Erase in the identified line everything from "x" to the end of the line (right). * @param {number} x The column from which to start erasing to the end of the line. diff --git a/src/utils/TestUtils.test.ts b/src/utils/TestUtils.test.ts index 8d47556093..ae83aed4fb 100644 --- a/src/utils/TestUtils.test.ts +++ b/src/utils/TestUtils.test.ts @@ -189,6 +189,12 @@ export class MockBuffer implements IBuffer { translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol?: number, endCol?: number): string { throw new Error('Method not implemented.'); } + nextStop(x?: number): number { + throw new Error('Method not implemented.'); + } + prevStop(x?: number): number { + throw new Error('Method not implemented.'); + } } export class MockViewport implements IViewport {