optimize copyFrom and clone for blank lines

This commit is contained in:
Jörg Breitbart
2026-08-18 16:36:57 +02:00
parent 29a7384233
commit fa3821adb9
3 changed files with 21 additions and 10 deletions
+15 -4
View File
@@ -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;
}
+2 -2
View File
@@ -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;
+4 -4
View File
@@ -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