From e9c648f5192df089876fabed416d6795dce31ffe Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 1 Jun 2026 21:07:55 -0700 Subject: [PATCH] fix(BufferReflow): clear stale isWrapped after larger reflow When widening the terminal unwraps a multi-row soft wrap and removes trailing buffer lines, the last retained row could still have isWrapped set, and the following line could still think it continued a removed row. That broke wrapped range translation. Clear isWrapped on the last retained row in the group and on the first line after the group when rows are removed during reflow. Co-authored-by: Cursor --- src/common/buffer/BufferReflow.test.ts | 23 +++++++++++++++++++++++ src/common/buffer/BufferReflow.ts | 5 +++++ 2 files changed, 28 insertions(+) diff --git a/src/common/buffer/BufferReflow.test.ts b/src/common/buffer/BufferReflow.test.ts index 8bcf5bf9c..cf14058ff 100644 --- a/src/common/buffer/BufferReflow.test.ts +++ b/src/common/buffer/BufferReflow.test.ts @@ -10,6 +10,7 @@ import { CellData } from './CellData'; import { NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE } from './Constants'; import { reflowLargerGetLinesToRemove, reflowSmallerGetNewLineLengths } from './BufferReflow'; import { IBufferLine } from './Types'; +import { createCellData, NULL_CELL_DATA } from '../TestUtils.test'; const TEST_STRING_CACHE = new BufferLineStringCache(); @@ -122,5 +123,27 @@ describe('BufferReflow', () => { const lines = createWrappedLines('abcde'); assert.notDeepEqual(reflowLargerGetLinesToRemove(lines, 1, 5, 10, nullCell, false), []); }); + + it('should clear isWrapped on the last retained row after unwrap', () => { + const lines = new CircularList(10); + const set2 = (line: BufferLine, s: string) => { + for (let i = 0; i < s.length; i++) { + line.setCell(i, createCellData(0, s[i], 1)); + } + }; + const l0 = new BufferLine(TEST_STRING_CACHE, 2); + set2(l0, 'ab'); + const l1 = new BufferLine(TEST_STRING_CACHE, 2, undefined, true); + set2(l1, 'cd'); + const l2 = new BufferLine(TEST_STRING_CACHE, 2, undefined, true); + set2(l2, 'ef'); + lines.push(l0); + lines.push(l1); + lines.push(l2); + + reflowLargerGetLinesToRemove(lines, 2, 6, 99, NULL_CELL_DATA, false); + + assert.equal(l1.isWrapped, false); + }); }); }); diff --git a/src/common/buffer/BufferReflow.ts b/src/common/buffer/BufferReflow.ts index 2c0fb74ba..2599f059f 100644 --- a/src/common/buffer/BufferReflow.ts +++ b/src/common/buffer/BufferReflow.ts @@ -99,6 +99,11 @@ export function reflowLargerGetLinesToRemove(lines: CircularList, o } if (countToRemove > 0) { + wrappedLines[destLineIndex].isWrapped = false; + const lineAfterGroup = lines.get(y + wrappedLines.length); + if (lineAfterGroup) { + lineAfterGroup.isWrapped = false; + } toRemove.push(y + wrappedLines.length - countToRemove); // index toRemove.push(countToRemove); }