diff --git a/src/common/buffer/BufferLine.ts b/src/common/buffer/BufferLine.ts index 30b4ed3bb..ff682e25f 100644 --- a/src/common/buffer/BufferLine.ts +++ b/src/common/buffer/BufferLine.ts @@ -458,7 +458,7 @@ export class BufferLine implements IBufferLine { } /** alter to a full copy of line */ - public copyFrom(line: BufferLine): void { + public copyFrom(line: BufferLine, blank?: boolean): void { this._invalidateStringCache(); if (this.length !== line.length) { this._data = new Uint32Array(line._data); @@ -467,16 +467,27 @@ export class BufferLine implements IBufferLine { this._data.set(line._data); } this.length = line.length; - this._copySparseMapsFrom(line); + if (blank) { + // a blank line may never hold combined or extended attrs, + // thus we can skip handling them + this._combined = {}; + this._extendedAttrs = {}; + } else { + this._copySparseMapsFrom(line); + } this.isWrapped = line.isWrapped; } /** create a new clone */ - public clone(): IBufferLine { + public clone(blank?: boolean): IBufferLine { const newLine = new BufferLine(this._stringCache, 0, undefined, false); newLine._data = new Uint32Array(this._data); newLine.length = this.length; - newLine._copySparseMapsFrom(this); + if (!blank) { + // a blank line may never hold combined or extended attrs, + // thus we can skip handling them + newLine._copySparseMapsFrom(this); + } newLine.isWrapped = this.isWrapped; return newLine; } diff --git a/src/common/buffer/Types.ts b/src/common/buffer/Types.ts index 994ca0f43..a7cf0685a 100644 --- a/src/common/buffer/Types.ts +++ b/src/common/buffer/Types.ts @@ -131,8 +131,8 @@ export interface IBufferLine { resize(cols: number, fill: ICellData): boolean; cleanupMemory(): number; fill(fillCellData: ICellData, respectProtect?: boolean): void; - copyFrom(line: IBufferLine): void; - clone(): IBufferLine; + copyFrom(line: IBufferLine, blank?: boolean): void; + clone(blank?: boolean): IBufferLine; getTrimmedLength(): number; getNoBgTrimmedLength(): number; translateToString(trimRight?: boolean, startCol?: number, endCol?: number, outColumns?: number[]): string; diff --git a/src/common/services/BufferService.ts b/src/common/services/BufferService.ts index 21b0a163a..7abdac978 100644 --- a/src/common/services/BufferService.ts +++ b/src/common/services/BufferService.ts @@ -86,12 +86,12 @@ export class BufferService extends Disposable implements IBufferService { // Insert the line using the fastest method if (bottomRow === buffer.lines.length - 1) { if (willBufferBeTrimmed) { - buffer.lines.recycle().copyFrom(newLine); + buffer.lines.recycle().copyFrom(newLine, true); } else { - buffer.lines.push(newLine.clone()); + buffer.lines.push(newLine.clone(true)); } } else { - buffer.lines.splice(bottomRow + 1, 0, newLine.clone()); + buffer.lines.splice(bottomRow + 1, 0, newLine.clone(true)); } // Only adjust ybase and ydisp when the buffer is not trimmed @@ -113,7 +113,7 @@ export class BufferService extends Disposable implements IBufferService { // scrollback, instead we can just shift them in-place. const scrollRegionHeight = bottomRow - topRow + 1 /* as it's zero-based */; buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1); - buffer.lines.set(bottomRow, newLine.clone()); + buffer.lines.set(bottomRow, newLine.clone(true)); } // Move the viewport to the bottom of the buffer unless the user is