From bc86664726bf2f1f0ca2e700f70545a125f3b369 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 25 Aug 2017 13:14:30 -0700 Subject: [PATCH] Improve Buffer.resize to work with uninitialized buffers Fixes #924 --- src/Buffer.ts | 138 +++++++++++++++++++++++++------------------------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/src/Buffer.ts b/src/Buffer.ts index 53645837..4f81025f 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -94,11 +94,6 @@ export class Buffer implements IBuffer { * @param newRows The new number of rows. */ public resize(newCols: number, newRows: number): void { - // Don't resize the buffer if it's empty and hasn't been used yet. - if (this._lines.length === 0) { - return; - } - // Increase max length if needed before adjustments to allow space to fill // as required. const newMaxLength = this._getCorrectBufferLength(newRows); @@ -106,83 +101,88 @@ export class Buffer implements IBuffer { this._lines.maxLength = newMaxLength; } - // Deal with columns increasing (we don't do anything when columns reduce) - if (this._terminal.cols < newCols) { - const ch: CharData = [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(undefined, undefined, newCols)); - } - while (this._lines.get(i).length < newCols) { - this._lines.get(i).push(ch); + // The following adjustments should only happen if the buffer has been + // initialized/filled. + if (this._lines.length > 0) { + // Deal with columns increasing (we don't do anything when columns reduce) + if (this._terminal.cols < newCols) { + const ch: CharData = [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(undefined, undefined, newCols)); + } + while (this._lines.get(i).length < newCols) { + this._lines.get(i).push(ch); + } } } - } - // Resize rows in both directions as needed - let addToY = 0; - if (this._terminal.rows < newRows) { - for (let y = this._terminal.rows; y < newRows; y++) { - if (this._lines.length < newRows + this.ybase) { - if (this.ybase > 0 && this._lines.length <= this.ybase + this.y + addToY + 1) { - // There is room above the buffer and there are no empty elements below the line, - // scroll up - this.ybase--; - addToY++; - if (this.ydisp > 0) { - // Viewport is at the top of the buffer, must increase downwards - this.ydisp--; + // Resize rows in both directions as needed + let addToY = 0; + if (this._terminal.rows < newRows) { + for (let y = this._terminal.rows; y < newRows; y++) { + if (this._lines.length < newRows + this.ybase) { + if (this.ybase > 0 && this._lines.length <= this.ybase + this.y + addToY + 1) { + // There is room above the buffer and there are no empty elements below the line, + // scroll up + this.ybase--; + addToY++; + if (this.ydisp > 0) { + // Viewport is at the top of the buffer, must increase downwards + this.ydisp--; + } + } 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(undefined, undefined, newCols)); + } + } + } + } else { // (this._terminal.rows >= newRows) + for (let y = this._terminal.rows; y > newRows; y--) { + if (this._lines.length > newRows + this.ybase) { + if (this._lines.length > this.ybase + this.y + 1) { + // The line is a blank line below the cursor, remove it + this._lines.pop(); + } else { + // The line is the cursor, scroll down + this.ybase++; + this.ydisp++; } - } 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(undefined, undefined, newCols)); } } } - } else { // (this._terminal.rows >= newRows) - for (let y = this._terminal.rows; y > newRows; y--) { - if (this._lines.length > newRows + this.ybase) { - if (this._lines.length > this.ybase + this.y + 1) { - // The line is a blank line below the cursor, remove it - this._lines.pop(); - } else { - // The line is the cursor, scroll down - this.ybase++; - this.ydisp++; - } + + // Reduce max length if needed after adjustments, this is done after as it + // would otherwise cut data from the bottom of the buffer. + if (newMaxLength < this._lines.maxLength) { + // Trim from the top of the buffer and adjust ybase and ydisp. + const amountToTrim = this._lines.length - newMaxLength; + if (amountToTrim > 0) { + this._lines.trimStart(amountToTrim); + this.ybase = Math.max(this.ybase - amountToTrim, 0); + this.ydisp = Math.max(this.ydisp - amountToTrim, 0); } + this._lines.maxLength = newMaxLength; } - } - // Reduce max length if needed after adjustments, this is done after as it - // would otherwise cut data from the bottom of the buffer. - if (newMaxLength < this._lines.maxLength) { - // Trim from the top of the buffer and adjust ybase and ydisp. - const amountToTrim = this._lines.length - newMaxLength; - if (amountToTrim > 0) { - this._lines.trimStart(amountToTrim); - this.ybase = Math.max(this.ybase - amountToTrim, 0); - this.ydisp = Math.max(this.ydisp - amountToTrim, 0); + // Make sure that the cursor stays on screen + if (this.y >= newRows) { + this.y = newRows - 1; } - this._lines.maxLength = newMaxLength; + if (addToY) { + this.y += addToY; + } + + if (this.x >= newCols) { + this.x = newCols - 1; + } + + this.scrollTop = 0; } - // Make sure that the cursor stays on screen - if (this.y >= newRows) { - this.y = newRows - 1; - } - if (addToY) { - this.y += addToY; - } - - if (this.x >= newCols) { - this.x = newCols - 1; - } - - this.scrollTop = 0; this.scrollBottom = newRows - 1; }