From 41463d8eb5ae6e604eb524c9be7787935f5a75d7 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 25 Aug 2017 12:41:53 -0700 Subject: [PATCH] Make reverseIndex scroll region-aware This was causing a issue when scrollback was 0 as the start of the buffer was getting copied --- src/InputHandler.ts | 3 -- src/Terminal.ts | 107 ++++---------------------------------------- test/bar | 0 test/foo | 0 4 files changed, 9 insertions(+), 101 deletions(-) create mode 100644 test/bar create mode 100644 test/foo diff --git a/src/InputHandler.ts b/src/InputHandler.ts index e6ab5540..f2d97751 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -464,13 +464,10 @@ export class InputHandler implements IInputHandler { let j: number; j = this._terminal.rows - 1 - this._terminal.buffer.scrollBottom; j = this._terminal.rows - 1 + this._terminal.buffer.ybase - j; - console.log('deleteLines', params); while (param--) { // test: echo -e '\e[44m\e[1M\e[0m' // blankLine(true) - xterm/linux behavior - console.log('splice delete row: ' + (row - 1) + '(' + this._terminal.buffer.lines.get(row - 1)[0][1] + ')'); this._terminal.buffer.lines.splice(row - 1, 1); - console.log('splice add blank row: ' + (j) + '(' + this._terminal.buffer.lines.get(j)[0][1] + ')'); this._terminal.buffer.lines.splice(j, 0, this._terminal.blankLine(true)); } diff --git a/src/Terminal.ts b/src/Terminal.ts index fa3161f0..ea3800d0 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -1163,133 +1163,44 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT /** * Scroll the terminal down 1 row, creating a blank line. - * @param {boolean} isWrapped Whether the new line is wrapped from the previous - * line. + * @param isWrapped Whether the new line is wrapped from the previous line. */ public scroll(isWrapped?: boolean): void { - // The problem is caused when scrollback = 0. This section was written - // around the assumption that there would be buffer to trim when necessary. - - - // shiftElements should be used here - - // If scrollTop is set (non-zero), we should shiftElements - // scrollBottom defines the position at which the new element is inserted - - // Note that both scrollBottom and scrollTop need to be handled individually - // because they can be set to terminal.rows or 0 respectively - - // Don't mess with ybase temporarily, asking for trouble - - // This should work with minimal effort utilizing the CiruclarList - - // TODO: Need to hold onto top given the if? const newLine = this.blankLine(undefined, isWrapped); const topRow = this.buffer.ybase + this.buffer.scrollTop; let bottomRow = this.buffer.ybase + this.buffer.scrollBottom; - - -// TODO: There's a problem with ybase going beyond scrollback? - - - console.log('bottomRow', bottomRow); - console.log('this.buffer.scrollTop: ' + this.buffer.scrollTop); if (this.buffer.scrollTop === 0) { + // Determine whether the buffer is going to be trimmed after insertion. const willBufferBeTrimmed = this.buffer.lines.length === this.buffer.lines.maxLength; - // Remove the line first if there is no scrollback so the list is not - // trimmed - if (!this.buffer.hasScrollback) { - this.buffer.lines.splice(topRow, 1); - // Adjust bottomRow to make up for the deleted row - // bottomRow--; - } - + // Insert the line using the fastest method if (bottomRow === this.buffer.lines.length - 1) { - // Pushing when possible is faster than splicing this.buffer.lines.push(newLine); - console.log('push'); } else { - // Insert a row *below* the bottomRow, pushing the top row into the scrollback - if (!this.buffer.hasScrollback) { - // A line is deleted in this case so bottomRow is pushed up - this.buffer.lines.splice(bottomRow, 0, newLine); - } else { - this.buffer.lines.splice(bottomRow + 1, 0, newLine); - } - console.log('splice'); + this.buffer.lines.splice(bottomRow + 1, 0, newLine); } // Only adjust ybase and ydisp when the buffer is not trimmed if (!willBufferBeTrimmed) { - console.log('increment ydisp/ybase'); this.buffer.ybase++; this.buffer.ydisp++; } - - console.log('this.buffer.ybase: ' + this.buffer.ybase); - console.log('this.buffer.ydisp: ' + this.buffer.ydisp); - } else { + // scrollTop is non-zero which means no line will be going to the + // scrollback, instead we can just shift them in-place. const scrollRegionHeight = bottomRow - topRow + 1/*as it's zero-based*/; - - console.log('shiftElements'); - console.log('topRow: ' + topRow + '(' + this.buffer.lines.get(topRow)[0][1] + ')'); - console.log('scrollRegionHeight: ' + scrollRegionHeight); - this.buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1); this.buffer.lines.set(bottomRow, newLine); } + // Move the viewport to the bottom of the buffer unless the user is + // scrolling. if (!this.userScrolling) { this.buffer.ydisp = this.buffer.ybase; } - - // Make room for the new row in lines - // const bufferNeedsTrimming = this.buffer.lines.length === this.buffer.lines.maxLength; - // if (bufferNeedsTrimming) { - // this.buffer.lines.trimStart(1); - // this.buffer.ybase--; - // this.buffer.ydisp = Math.max(this.buffer.ydisp - 1, 0); - // } - - // this.buffer.ybase++; - - // // Scroll the viewport down to the bottom if the user is not scrolling - // if (!this.userScrolling) { - // this.buffer.ydisp = this.buffer.ybase; - // } - - // // last line - // let row = this.buffer.ybase + this.rows - 1; - - // // subtract the bottom scroll region - // row -= this.rows - 1 - this.buffer.scrollBottom; - - // // Same as this? - // // row = this.buffer.ybase + this.buffer.scrollBottom; - - // if (row === this.buffer.lines.length) { - // // Optimization: pushing is faster than splicing when they amount to the same behavior - // this.buffer.lines.push(this.blankLine(undefined, isWrapped)); - // } else { - // // add our new line - // this.buffer.lines.splice(row, 0, this.blankLine(undefined, isWrapped)); - // } - - // if (this.buffer.scrollTop !== 0) { - // if (this.buffer.ybase !== 0) { - // this.buffer.ybase--; - // if (!this.userScrolling) { - // this.buffer.ydisp = this.buffer.ybase; - // } - // } - // this.buffer.lines.splice(this.buffer.ybase + this.buffer.scrollTop, 1); - // } - - // this.maxRange(); + // Flag rows that need updating this.updateRange(this.buffer.scrollTop); this.updateRange(this.buffer.scrollBottom); diff --git a/test/bar b/test/bar new file mode 100644 index 00000000..e69de29b diff --git a/test/foo b/test/foo new file mode 100644 index 00000000..e69de29b