diff --git a/src/Buffer.test.ts b/src/Buffer.test.ts index 81f3ba4c..ebd036d4 100644 --- a/src/Buffer.test.ts +++ b/src/Buffer.test.ts @@ -37,7 +37,7 @@ describe('Buffer', () => { describe('fillViewportRows', () => { it('should fill the buffer with blank lines based on the size of the viewport', () => { - const blankLineChar = BufferLine.blankLine(terminal.cols, DEFAULT_ATTR).get(0); + const blankLineChar = buffer.getBlankLine(DEFAULT_ATTR).get(0); buffer.fillViewportRows(); assert.equal(buffer.lines.length, INIT_ROWS); for (let y = 0; y < INIT_ROWS; y++) { @@ -184,7 +184,7 @@ describe('Buffer', () => { buffer.fillViewportRows(); // Create 10 extra blank lines for (let i = 0; i < 10; i++) { - buffer.lines.push(BufferLine.blankLine(terminal.cols, DEFAULT_ATTR)); + buffer.lines.push(buffer.getBlankLine(DEFAULT_ATTR)); } // Set cursor to the bottom of the buffer buffer.y = INIT_ROWS - 1; @@ -204,7 +204,7 @@ describe('Buffer', () => { buffer.fillViewportRows(); // Create 10 extra blank lines for (let i = 0; i < 10; i++) { - buffer.lines.push(BufferLine.blankLine(terminal.cols, DEFAULT_ATTR)); + buffer.lines.push(buffer.getBlankLine(DEFAULT_ATTR)); } // Set cursor to the bottom of the buffer buffer.y = INIT_ROWS - 1; diff --git a/src/Buffer.ts b/src/Buffer.ts index 914f0744..ea62edf2 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -78,8 +78,9 @@ export class Buffer implements IBuffer { } } - public getBlankLine(cols: number, attr: number, isWrapped?: boolean): IBufferLine { - return this._bufferLineConstructor.blankLine(cols, attr, isWrapped); + public getBlankLine(attr: number, isWrapped?: boolean): IBufferLine { + const fillCharData: CharData = [attr, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; + return new this._bufferLineConstructor(this._terminal.cols, fillCharData, isWrapped); } public get hasScrollback(): boolean { @@ -114,7 +115,7 @@ export class Buffer implements IBuffer { if (this.lines.length === 0) { let i = this._terminal.rows; while (i--) { - this.lines.push(BufferLine.blankLine(this._terminal.cols, DEFAULT_ATTR)); + this.lines.push(this.getBlankLine(DEFAULT_ATTR)); } } } @@ -175,7 +176,8 @@ export class Buffer implements IBuffer { } else { // Add a blank line if there is no buffer left at the top to scroll to, or if there // are blank lines after the cursor - this.lines.push(BufferLine.blankLine(newCols, DEFAULT_ATTR)); + const fillCharData: CharData = [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; + this.lines.push(new this._bufferLineConstructor(newCols, fillCharData)); } } } diff --git a/src/BufferLine.test.ts b/src/BufferLine.test.ts index 47073a4e..a4011f9e 100644 --- a/src/BufferLine.test.ts +++ b/src/BufferLine.test.ts @@ -5,7 +5,7 @@ import * as chai from 'chai'; import { BufferLine } from './BufferLine'; import { CharData, IBufferLine } from './Types'; -import { NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE, CHAR_DATA_ATTR_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CODE_INDEX } from './Buffer'; +import { NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE } from './Buffer'; class TestBufferLine extends BufferLine { @@ -36,16 +36,6 @@ describe('BufferLine', function(): void { chai.expect(line.get(0)).eql([123, 'a', 456, 'a'.charCodeAt(0)]); chai.expect(line.isWrapped).equals(true); }); - it('TerminalLine.blankLine', function(): void { - const line = TestBufferLine.blankLine(5, 123); - chai.expect(line.length).equals(5); - chai.expect(line.isWrapped).equals(false); - const ch = line.get(0); - chai.expect(ch[CHAR_DATA_ATTR_INDEX]).equals(123); - chai.expect(ch[CHAR_DATA_CHAR_INDEX]).equals(NULL_CELL_CHAR); - chai.expect(ch[CHAR_DATA_WIDTH_INDEX]).equals(NULL_CELL_WIDTH); - chai.expect(ch[CHAR_DATA_CODE_INDEX]).equals(NULL_CELL_CODE); - }); it('insertCells', function(): void { const line = new TestBufferLine(3); line.set(0, [1, 'a', 0, 'a'.charCodeAt(0)]); diff --git a/src/BufferLine.ts b/src/BufferLine.ts index c2bcb172..bcc9990e 100644 --- a/src/BufferLine.ts +++ b/src/BufferLine.ts @@ -9,10 +9,6 @@ import { NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR } from './Buffer'; * Class representing a terminal line. */ export class BufferLine implements IBufferLine { - static blankLine(cols: number, attr: number, isWrapped?: boolean): IBufferLine { - const ch: CharData = [attr, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; - return new BufferLine(cols, ch, isWrapped); - } protected _data: CharData[]; public isWrapped = false; public length: number; @@ -134,10 +130,6 @@ const enum Cell { * - provide getData/setData to directly access the data */ export class BufferLineTypedArray implements IBufferLine { - static blankLine(cols: number, attr: number, isWrapped?: boolean): IBufferLine { - const ch: CharData = [attr, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; - return new BufferLineTypedArray(cols, ch, isWrapped); - } protected _data: Uint32Array | null = null; protected _combined: {[index: number]: string} = {}; public length: number; diff --git a/src/InputHandler.ts b/src/InputHandler.ts index d0d6db47..400e9b93 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -13,7 +13,6 @@ import { wcwidth } from './CharWidth'; import { EscapeSequenceParser } from './EscapeSequenceParser'; import { ICharset } from './core/Types'; import { Disposable } from './common/Lifecycle'; -import { BufferLine } from './BufferLine'; /** * Map collect to glevel. Used in `selectCharset`. @@ -831,7 +830,7 @@ export class InputHandler extends Disposable implements IInputHandler { // test: echo -e '\e[44m\e[1L\e[0m' // blankLine(true) - xterm/linux behavior buffer.lines.splice(scrollBottomAbsolute - 1, 1); - buffer.lines.splice(row, 0, BufferLine.blankLine(this._terminal.cols, this._terminal.eraseAttr())); + buffer.lines.splice(row, 0, buffer.getBlankLine(this._terminal.eraseAttr())); } // this.maxRange(); @@ -861,7 +860,7 @@ export class InputHandler extends Disposable implements IInputHandler { // test: echo -e '\e[44m\e[1M\e[0m' // blankLine(true) - xterm/linux behavior buffer.lines.splice(row, 1); - buffer.lines.splice(j, 0, BufferLine.blankLine(this._terminal.cols, this._terminal.eraseAttr())); + buffer.lines.splice(j, 0, buffer.getBlankLine(this._terminal.eraseAttr())); } // this.maxRange(); @@ -893,7 +892,7 @@ export class InputHandler extends Disposable implements IInputHandler { while (param--) { buffer.lines.splice(buffer.ybase + buffer.scrollTop, 1); - buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 0, BufferLine.blankLine(this._terminal.cols, DEFAULT_ATTR)); + buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 0, buffer.getBlankLine(DEFAULT_ATTR)); } // this.maxRange(); this._terminal.updateRange(buffer.scrollTop); @@ -912,7 +911,7 @@ export class InputHandler extends Disposable implements IInputHandler { while (param--) { buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 1); - buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 0, BufferLine.blankLine(this._terminal.cols, DEFAULT_ATTR)); + buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 0, buffer.getBlankLine(DEFAULT_ATTR)); } // this.maxRange(); this._terminal.updateRange(buffer.scrollTop); diff --git a/src/Terminal.test.ts b/src/Terminal.test.ts index 789751d1..0111de75 100644 --- a/src/Terminal.test.ts +++ b/src/Terminal.test.ts @@ -7,7 +7,6 @@ import { assert, expect } from 'chai'; import { Terminal } from './Terminal'; import { MockViewport, MockCompositionHelper, MockRenderer } from './utils/TestUtils.test'; import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, DEFAULT_ATTR } from './Buffer'; -import { BufferLine } from './BufferLine'; const INIT_COLS = 80; const INIT_ROWS = 24; @@ -142,7 +141,7 @@ describe('term.js addons', () => { assert.equal(term.buffer.lines.length, term.rows); assert.deepEqual(term.buffer.lines.get(0), promptLine); for (let i = 1; i < term.rows; i++) { - assert.deepEqual(term.buffer.lines.get(i), BufferLine.blankLine(term.cols, DEFAULT_ATTR)); + assert.deepEqual(term.buffer.lines.get(i), term.buffer.getBlankLine(DEFAULT_ATTR)); } }); it('should clear a buffer larger than rows', () => { @@ -159,7 +158,7 @@ describe('term.js addons', () => { assert.equal(term.buffer.lines.length, term.rows); assert.deepEqual(term.buffer.lines.get(0), promptLine); for (let i = 1; i < term.rows; i++) { - assert.deepEqual(term.buffer.lines.get(i), BufferLine.blankLine(term.cols, DEFAULT_ATTR)); + assert.deepEqual(term.buffer.lines.get(i), term.buffer.getBlankLine(DEFAULT_ATTR)); } }); it('should not break the prompt when cleared twice', () => { @@ -172,7 +171,7 @@ describe('term.js addons', () => { assert.equal(term.buffer.lines.length, term.rows); assert.deepEqual(term.buffer.lines.get(0), promptLine); for (let i = 1; i < term.rows; i++) { - assert.deepEqual(term.buffer.lines.get(i), BufferLine.blankLine(term.cols, DEFAULT_ATTR)); + assert.deepEqual(term.buffer.lines.get(i), term.buffer.getBlankLine(DEFAULT_ATTR)); } }); }); diff --git a/src/Terminal.ts b/src/Terminal.ts index a1a66dc5..5c020371 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -1174,7 +1174,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II * @param isWrapped Whether the new line is wrapped from the previous line. */ public scroll(isWrapped?: boolean): void { - const newLine = this.buffer.getBlankLine(this.cols, DEFAULT_ATTR, isWrapped); + const newLine = this.buffer.getBlankLine(DEFAULT_ATTR, isWrapped); const topRow = this.buffer.ybase + this.buffer.scrollTop; const bottomRow = this.buffer.ybase + this.buffer.scrollBottom; @@ -1726,7 +1726,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II this.buffer.ybase = 0; this.buffer.y = 0; for (let i = 1; i < this.rows; i++) { - this.buffer.lines.push(this.buffer.getBlankLine(this.cols, DEFAULT_ATTR)); + this.buffer.lines.push(this.buffer.getBlankLine(DEFAULT_ATTR)); } this.refresh(0, this.rows - 1); this.emit('scroll', this.buffer.ydisp); @@ -1818,7 +1818,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II // blankLine(true) is xterm/linux behavior const scrollRegionHeight = this.buffer.scrollBottom - this.buffer.scrollTop; this.buffer.lines.shiftElements(this.buffer.y + this.buffer.ybase, scrollRegionHeight, 1); - this.buffer.lines.set(this.buffer.y + this.buffer.ybase, this.buffer.getBlankLine(this.cols, this.eraseAttr())); + this.buffer.lines.set(this.buffer.y + this.buffer.ybase, this.buffer.getBlankLine(this.eraseAttr())); this.updateRange(this.buffer.scrollTop); this.updateRange(this.buffer.scrollBottom); } else { diff --git a/src/Types.ts b/src/Types.ts index 5cc8cf19..03407cfc 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -284,6 +284,7 @@ export interface IBuffer { getWrappedRangeForLine(y: number): { first: number, last: number }; nextStop(x?: number): number; prevStop(x?: number): number; + getBlankLine(attr: number, isWrapped?: boolean): IBufferLine; } export interface IBufferSet extends IEventEmitter { @@ -527,5 +528,4 @@ export interface IBufferLine { export interface IBufferLineConstructor { new(cols: number, fillCharData?: CharData, isWrapped?: boolean): IBufferLine; - blankLine(cols: number, attr: number, isWrapped?: boolean): IBufferLine; } diff --git a/src/utils/TestUtils.test.ts b/src/utils/TestUtils.test.ts index b9bb0348..a5de2b69 100644 --- a/src/utils/TestUtils.test.ts +++ b/src/utils/TestUtils.test.ts @@ -4,10 +4,11 @@ */ import { IColorSet, IRenderer, IRenderDimensions, IColorManager } from '../renderer/Types'; -import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, ICircularList, ILinkifier, IMouseHelper, ILinkMatcherOptions, XtermListener, CharacterJoinerHandler, IBufferLine } from '../Types'; -import { Buffer } from '../Buffer'; +import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, ICircularList, ILinkifier, IMouseHelper, ILinkMatcherOptions, XtermListener, CharacterJoinerHandler, IBufferLine, CharData } from '../Types'; +import { Buffer, NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH } from '../Buffer'; import * as Browser from '../shared/utils/Browser'; import { ITheme, IDisposable, IMarker } from 'xterm'; +import { BufferLine } from '../BufferLine'; export class MockTerminal implements ITerminal { markers: IMarker[]; @@ -310,6 +311,10 @@ export class MockBuffer implements IBuffer { setLines(lines: ICircularList): void { this.lines = lines; } + getBlankLine(attr: number, isWrapped: boolean = false): IBufferLine { + const fillCharData: CharData = [attr, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; + return new BufferLine(80, fillCharData, isWrapped); + } } export class MockRenderer implements IRenderer {