diff --git a/src/Buffer.ts b/src/Buffer.ts index 74750a8b..6b247afe 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -233,6 +233,83 @@ export class Buffer implements IBuffer { } this.scrollBottom = newRows - 1; + + if (this._terminal.options.experimentalBufferLineImpl === 'TypedArray') { + this._reflow(newCols, newRows); + } + } + + private _reflow(newCols: number, newRows: number): void { + if (this._terminal.cols === newCols) { + return; + } + + // Iterate through rows, ignore the last one as it cannot be wrapped + for (let y = 0; y < this.lines.length - 1; y++) { + // Check if this row is wrapped + let i = y; + let nextLine = this.lines.get(++i) as BufferLine; + if (!nextLine.isWrapped) { + continue; + } + + // Check how many lines it's wrapped for + const wrappedLines: BufferLine[] = [this.lines.get(y) as BufferLine]; + while (nextLine.isWrapped) { + wrappedLines.push(nextLine); + nextLine = this.lines.get(++i) as BufferLine; + } + + if (newCols > this._terminal.cols) { + let destLineIndex = 0; + let destCol = this._terminal.cols; + let srcLineIndex = 1; + let srcCol = 0; + while (srcLineIndex < wrappedLines.length) { + const srcRemainingCells = this._terminal.cols - srcCol; + const destRemainingCells = newCols - destCol; + const cellsToCopy = Math.min(srcRemainingCells, destRemainingCells); + wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol, destCol, cellsToCopy); + destCol += cellsToCopy; + if (destCol === newCols) { + destLineIndex++; + destCol = 0; + } + srcCol += cellsToCopy; + if (srcCol === this._terminal.cols) { + srcLineIndex++; + srcCol = 0; + } + } + + // Work backwards and remove any rows at the end that only contain null cells + let countToRemove = 0; + for (let i = wrappedLines.length - 1; i > 0; i--) { + if (wrappedLines[i].getTrimmedLength() === 0) { + countToRemove++; + } else { + break; + } + } + + // Remove rows and adjust cursor + if (countToRemove > 0) { + this.lines.splice(y + wrappedLines.length - countToRemove, countToRemove); + while (countToRemove-- > 0) { + if (this.ybase === 0) { + this.y--; + } else { + if (this.ydisp === this.ybase) { + this.ydisp--; + } + this.ybase--; + } + } + } + } else { + + } + } } /** diff --git a/src/BufferLine.ts b/src/BufferLine.ts index 3f93af62..aafc9051 100644 --- a/src/BufferLine.ts +++ b/src/BufferLine.ts @@ -304,6 +304,16 @@ export class BufferLine implements IBufferLine { return 0; } + public copyCellsFrom(src: BufferLine, srcCol: number, destCol: number, length: number): void { + console.log(' copyCellsFrom', srcCol, destCol, length); + const srcData = src._data; + for (let cell = 0; cell < length; cell++) { + for (let i = 0; i < CELL_SIZE; i++) { + this._data[(destCol + cell) * CELL_SIZE + i] = srcData[(srcCol + cell) * CELL_SIZE + i]; + } + } + } + public translateToString(trimRight: boolean = false, startCol: number = 0, endCol: number = this.length): string { if (trimRight) { endCol = Math.min(endCol, this.getTrimmedLength());