diff --git a/src/Buffer.test.ts b/src/Buffer.test.ts index 99bd6d0fe5..1e2209155b 100644 --- a/src/Buffer.test.ts +++ b/src/Buffer.test.ts @@ -24,9 +24,9 @@ describe('Buffer', () => { }); describe('constructor', () => { - it('should create a CircularList with max length equal to scrollback, for its lines', () => { + it('should create a CircularList with max length equal to rows + scrollback, for its lines', () => { assert.instanceOf(buffer.lines, CircularList); - assert.equal(buffer.lines.maxLength, terminal.options.scrollback); + assert.equal(buffer.lines.maxLength, terminal.rows + terminal.options.scrollback); }); it('should set the Buffer\'s scrollBottom value equal to the terminal\'s rows -1', () => { assert.equal(buffer.scrollBottom, terminal.rows - 1); diff --git a/src/Buffer.ts b/src/Buffer.ts index eb346d5bc1..9d2222ff68 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -67,7 +67,7 @@ export class Buffer implements IBuffer { this.scrollBottom = 0; this.scrollTop = 0; this.tabs = {}; - this._lines = new CircularList(this._terminal.options.scrollback); + this._lines = new CircularList(this._terminal.rows + this._terminal.options.scrollback); this.scrollBottom = this._terminal.rows - 1; } diff --git a/src/BufferSet.ts b/src/BufferSet.ts index 24d6c31462..9136c5fb49 100644 --- a/src/BufferSet.ts +++ b/src/BufferSet.ts @@ -76,6 +76,17 @@ export class BufferSet extends EventEmitter implements IBufferSet { this.emit('activate', this._alt); } + /** + * Refreshes the max length of the buffer set, this should be called whenever + * terminal rows or scrollback changes. + * @param rows The number of terminal rows. + */ + public refreshMaxLength(rows: number): void { + this._normal.lines.maxLength = rows + this._terminal.options.scrollback; + // TODO: The alt buffer should never have scrollback, see https://github.com/sourcelair/xterm.js/issues/802 + this._alt.lines.maxLength = rows + this._terminal.options.scrollback; + } + /** * Resizes both normal and alt buffers, adjusting their data accordingly. * @param newCols The new number of columns. @@ -84,5 +95,6 @@ export class BufferSet extends EventEmitter implements IBufferSet { public resize(newCols: number, newRows: number): void { this._normal.resize(newCols, newRows); this._alt.resize(newCols, newRows); + this.refreshMaxLength(newRows); } } diff --git a/src/Terminal.ts b/src/Terminal.ts index cd44e7fb76..2afb45023e 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -439,18 +439,10 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT } switch (key) { case 'scrollback': - if (value < this.rows) { - let msg = 'Setting the scrollback value less than the number of rows '; - - msg += `(${this.rows}) is not allowed.`; - - console.warn(msg); - return; - } - if (this.options[key] !== value) { - if (this.buffer.lines.length > value) { - const amountToTrim = this.buffer.lines.length - value; + const newBufferLength = this.rows + value; + if (this.buffer.lines.length > newBufferLength) { + const amountToTrim = this.buffer.lines.length - newBufferLength; const needsRefresh = (this.buffer.ydisp - amountToTrim < 0); this.buffer.lines.trimStart(amountToTrim); this.buffer.ybase = Math.max(this.buffer.ybase - amountToTrim, 0); @@ -459,8 +451,6 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT this.refresh(0, this.rows - 1); } } - this.buffer.lines.maxLength = value; - this.viewport.syncScrollArea(); } break; } @@ -473,6 +463,10 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline'); this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar'); break; + case 'scrollback': + this.buffers.refreshMaxLength(this.rows); + this.viewport.syncScrollArea(); + break; case 'tabStopWidth': this.setupStops(); break; } } @@ -1935,10 +1929,6 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT return; } - if (y > this.getOption('scrollback')) { - this.setOption('scrollback', y); - } - let line; let el; let i; diff --git a/src/test/test.js b/src/test/test.js index 5c4dd5f224..51d1644c54 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -44,16 +44,6 @@ describe('xterm.js', function() { }); describe('setOption', function() { - let originalWarn; - let warnCallCount; - beforeEach(() => { - originalWarn = console.warn; - warnCallCount = 0; - console.warn = () => warnCallCount++; - }); - afterEach(() => { - console.warn = originalWarn; - }); it('should set the option correctly', function() { xterm.setOption('cursorBlink', true); assert.equal(xterm.cursorBlink, true); @@ -63,12 +53,7 @@ describe('xterm.js', function() { assert.equal(xterm.options.cursorBlink, false); }); it('should throw when setting a non-existant option', function() { - assert.throws(xterm.setOption.bind(xterm, 'fake', true)); - }); - it('should warn and do nothing when scrollback is less than number of rows', function() { - xterm.setOption('scrollback', xterm.rows - 1); - assert.equal(xterm.getOption('scrollback'), 1000); - assert.equal(warnCallCount, 1); + assert.throws(() => xterm.setOption('fake', true)); }); }); diff --git a/src/utils/CircularList.ts b/src/utils/CircularList.ts index 373d78b053..23d6c33738 100644 --- a/src/utils/CircularList.ts +++ b/src/utils/CircularList.ts @@ -25,6 +25,9 @@ export class CircularList extends EventEmitter implements ICircularList { } public set maxLength(newMaxLength: number) { + if (this.maxLength === newMaxLength) { + return; + } // Reconstruct array, starting at index 0. Only transfer values from the // indexes 0 to length. let newArray = new Array(newMaxLength);