From 0c25c3ef70e07b9992b2eafea3f7da2a1df819a0 Mon Sep 17 00:00:00 2001 From: Per Bothner Date: Thu, 26 Mar 2026 18:25:41 -0700 Subject: [PATCH] Change isWrapped handing of _eraseInBufferLine and its callers Replace clearWrap parameter by start==0 test. Add clearing wrap of folowing line if erasing to end of line. This fixes some minor issues and inconsistencies. --- src/common/InputHandler.test.ts | 7 ++++++- src/common/InputHandler.ts | 34 +++++++++++++++++---------------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index f9da81a25e..44744274f5 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -459,8 +459,11 @@ describe('InputHandler', () => { await resetToBaseState(); bufferService.buffer.y = 2; bufferService.buffer.x = 40; + assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, true); + assert.equal(bufferService.buffer.lines.get(3)!.isWrapped, true); inputHandler.eraseInLine(Params.fromArray([0])); assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, true); + assert.equal(bufferService.buffer.lines.get(3)!.isWrapped, false); bufferService.buffer.y = 2; bufferService.buffer.x = 0; inputHandler.eraseInLine(Params.fromArray([0])); @@ -471,7 +474,8 @@ describe('InputHandler', () => { bufferService.buffer.y = 2; bufferService.buffer.x = 40; inputHandler.eraseInLine(Params.fromArray([1])); - assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, true); + assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, false); + assert.equal(bufferService.buffer.lines.get(3)!.isWrapped, true); // params[2] - erase complete line await resetToBaseState(); @@ -479,6 +483,7 @@ describe('InputHandler', () => { bufferService.buffer.x = 40; inputHandler.eraseInLine(Params.fromArray([2])); assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, false); + assert.equal(bufferService.buffer.lines.get(3)!.isWrapped, false); }); it('ED2 with scrollOnEraseInDisplay turned on', async () => { const inputHandler = new TestInputHandler( diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 68265c5df4..ee4bfe502f 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -1183,14 +1183,16 @@ export class InputHandler extends Disposable implements IInputHandler { /** * Helper method to erase cells in a terminal row. * The cell gets replaced with the eraseChar of the terminal. + * Clear isWrapped if start===0; + * clear isWrapped of next line if end >= cols. * @param y The row index relative to the viewport. * @param start The start x index of the range to be erased. * @param end The end x index of the range to be erased (exclusive). - * @param clearWrap clear the isWrapped flag * @param respectProtect Whether to respect the protection attribute (DECSCA). */ - private _eraseInBufferLine(y: number, start: number, end: number, clearWrap: boolean = false, respectProtect: boolean = false): void { - const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y); + private _eraseInBufferLine(y: number, start: number, end: number, respectProtect: boolean = false): void { + const yAbs = y + this._activeBuffer.ybase; + const line = this._activeBuffer.lines.get(yAbs); if (!line) { return; } @@ -1200,9 +1202,16 @@ export class InputHandler extends Disposable implements IInputHandler { this._activeBuffer.getNullCell(this._eraseAttrData()), respectProtect ); - if (clearWrap) { + if (start === 0) { line.isWrapped = false; } + if (end >= this._bufferService.cols) { + // Deleted entire previous line. This next line can no longer be wrapped. + const nextLine = this._activeBuffer.lines.get(yAbs + 1); + if (nextLine) { + nextLine.isWrapped = false; + } + } } /** @@ -1250,7 +1259,7 @@ export class InputHandler extends Disposable implements IInputHandler { case 0: j = this._activeBuffer.y; this._dirtyRowTracker.markDirty(j); - this._eraseInBufferLine(j++, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0, respectProtect); + this._eraseInBufferLine(j++, this._activeBuffer.x, this._bufferService.cols, respectProtect); for (; j < this._bufferService.rows; j++) { this._resetBufferLine(j, respectProtect); } @@ -1260,14 +1269,7 @@ export class InputHandler extends Disposable implements IInputHandler { j = this._activeBuffer.y; this._dirtyRowTracker.markDirty(j); // Deleted front part of line and everything before. This line will no longer be wrapped. - this._eraseInBufferLine(j, 0, this._activeBuffer.x + 1, true, respectProtect); - if (this._activeBuffer.x + 1 >= this._bufferService.cols) { - // Deleted entire previous line. This next line can no longer be wrapped. - const nextLine = this._activeBuffer.lines.get(j + 1); - if (nextLine) { - nextLine.isWrapped = false; - } - } + this._eraseInBufferLine(j, 0, this._activeBuffer.x + 1, respectProtect); while (j--) { this._resetBufferLine(j, respectProtect); } @@ -1337,13 +1339,13 @@ export class InputHandler extends Disposable implements IInputHandler { this._restrictCursor(this._bufferService.cols); switch (params.params[0]) { case 0: - this._eraseInBufferLine(this._activeBuffer.y, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0, respectProtect); + this._eraseInBufferLine(this._activeBuffer.y, this._activeBuffer.x, this._bufferService.cols, respectProtect); break; case 1: - this._eraseInBufferLine(this._activeBuffer.y, 0, this._activeBuffer.x + 1, false, respectProtect); + this._eraseInBufferLine(this._activeBuffer.y, 0, this._activeBuffer.x + 1, respectProtect); break; case 2: - this._eraseInBufferLine(this._activeBuffer.y, 0, this._bufferService.cols, true, respectProtect); + this._eraseInBufferLine(this._activeBuffer.y, 0, this._bufferService.cols, respectProtect); break; } this._dirtyRowTracker.markDirty(this._activeBuffer.y);