From bb526aaa888685f613c89d64482af3d59925519c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 8 Aug 2017 12:59:02 -0700 Subject: [PATCH] Fix exception when resizing both dimensions This happened because buffers now resize themselves but they were relying on Terminal to give them a blank line. The blank line was coming back with the old columns value, causing an NPE. Fixes #860 --- src/Buffer.test.ts | 11 +++++++++++ src/Buffer.ts | 6 ++++-- src/Interfaces.ts | 2 +- src/utils/TestUtils.ts | 5 +++-- src/xterm.js | 5 +++-- 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Buffer.test.ts b/src/Buffer.test.ts index 5883a8b..e73ae28 100644 --- a/src/Buffer.test.ts +++ b/src/Buffer.test.ts @@ -143,5 +143,16 @@ describe('Buffer', () => { }); }); }); + + describe('row and column increased', () => { + it('should resize properly', () => { + buffer.fillViewportRows(); + buffer.resize(INIT_COLS + 5, INIT_ROWS + 5); + assert.equal(buffer.lines.length, INIT_ROWS + 5); + for (let i = 0; i < INIT_ROWS + 5; i++) { + assert.equal(buffer.lines.get(i).length, INIT_COLS + 5); + } + }); + }); }); }); diff --git a/src/Buffer.ts b/src/Buffer.ts index ba47d0c..d64a92b 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -85,8 +85,10 @@ export class Buffer implements IBuffer { if (this._terminal.cols < newCols) { const ch: [number, string, number] = [this._terminal.defAttr, ' ', 1]; // does xterm use the default attr? for (let i = 0; i < this._lines.length; i++) { + // TODO: This should be removed, with tests setup for the case that was + // causing the underlying bug, see https://github.com/sourcelair/xterm.js/issues/824 if (this._lines.get(i) === undefined) { - this._lines.set(i, this._terminal.blankLine()); + this._lines.set(i, this._terminal.blankLine(undefined, undefined, newCols)); } while (this._lines.get(i).length < newCols) { this._lines.get(i).push(ch); @@ -111,7 +113,7 @@ 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(this._terminal.blankLine()); + this._lines.push(this._terminal.blankLine(undefined, undefined, newCols)); } } } diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 70a46d4..f55719a 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -48,7 +48,7 @@ export interface ITerminal { emit(event: string, data: any); reset(): void; showCursor(): void; - blankLine(cur?: boolean, isWrapped?: boolean); + blankLine(cur?: boolean, isWrapped?: boolean, cols?: number); } export interface IBuffer { diff --git a/src/utils/TestUtils.ts b/src/utils/TestUtils.ts index fbb1726..eae34cc 100644 --- a/src/utils/TestUtils.ts +++ b/src/utils/TestUtils.ts @@ -43,9 +43,10 @@ export class MockTerminal implements ITerminal { showCursor(): void { throw new Error('Method not implemented.'); } - blankLine(cur?: boolean, isWrapped?: boolean) { + blankLine(cur?: boolean, isWrapped?: boolean, cols?: number) { const line = []; - for (let i = 0; i < this.cols; i++) { + cols = cols || this.cols; + for (let i = 0; i < cols; i++) { line.push([0, ' ', 1]); } return line; diff --git a/src/xterm.js b/src/xterm.js index e9e3465..38e7b9c 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2091,7 +2091,7 @@ Terminal.prototype.eraseLine = function(y) { * @param {number} cur First bunch of data for each "blank" character. * @param {boolean} isWrapped Whether the new line is wrapped from the previous line. */ -Terminal.prototype.blankLine = function(cur, isWrapped) { +Terminal.prototype.blankLine = function(cur, isWrapped, cols) { var attr = cur ? this.eraseAttr() : this.defAttr; @@ -2106,7 +2106,8 @@ Terminal.prototype.blankLine = function(cur, isWrapped) { line.isWrapped = isWrapped; } - for (; i < this.cols; i++) { + cols = cols || this.cols; + for (; i < cols; i++) { line[i] = ch; }