Skip to content

fix(buffer): copyCellsFrom metadata scope and reflow isWrapped cleanup#5997

Draft
Tyriar wants to merge 3 commits into
masterfrom
fix/buffer-copy-and-reflow-wrap
Draft

fix(buffer): copyCellsFrom metadata scope and reflow isWrapped cleanup#5997
Tyriar wants to merge 3 commits into
masterfrom
fix/buffer-copy-and-reflow-wrap

Conversation

@Tyriar

@Tyriar Tyriar commented Jun 3, 2026

Copy link
Copy Markdown
Member

Cherry-picks from Tyriar/explore-correctness (commits 992cc5c, cd4da10d), with a small merge adaptation on master for _copyCellMapsFrom.

1. BufferLine.copyCellsFrom — limit combined/extended metadata to copied range

copyCellsFrom copied Uint32 cell data only for the requested column range, but previously migrated every _combined entry with key >= srcCol. Partial line copies during reflow and wraparound could therefore attach grapheme metadata to unrelated destination columns.

Fix: Copy combined and extended attributes only per cell in the copied range, and delete stale entries on the destination when the source cell does not use them. On current master, this is implemented by extending _copyCellMapsFrom (used by copyCellsFrom and copyFrom) to clear stale _combined / _extendedAttrs keys when flags are absent.

Risk: Any path that partially copies cells between lines (reflow, wraparound, scroll regions).

Tests: BufferLine.test.tscopyCellsFrom / should only move combined data within the copied range.

2. reflowLargerGetLinesToRemove — 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 string translation.

Fix: When rows are removed during reflow, clear isWrapped on the last retained row in the group (wrappedLines[destLineIndex]) and on the first line after the group if present.

Risk: Resize/reflow and any feature that depends on correct wrap continuation across buffer lines (search, selection, translation).

Tests: BufferReflow.test.tsreflowLargerGetLinesToRemove / should clear isWrapped on the last retained row after unwrap, plus existing cursor/reflow guard tests on master.

Verification

npm run build && npm run esbuild
npm run test-unit -- **/BufferLine.test.js
npm run test-unit -- **/BufferReflow.test.js
Open in Web Open in Cursor 

Tyriar and others added 3 commits June 3, 2026 03:36
copyCellsFrom copied Uint32 cell data only for the requested column
range but migrated every combined entry with key >= srcCol, which could
attach grapheme metadata to unrelated destination columns during
partial line copies in reflow and wraparound.

Copy combined and extended attributes only per copied cell and clear
stale entries on the destination when the source cell does not use
them.

Co-authored-by: Cursor <cursoragent@cursor.com>
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 <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant