Skip to content

fix(InputHandler): isWrapped correctness after erase and column ops#5995

Draft
Tyriar wants to merge 3 commits into
masterfrom
fix/inputhandler-iswrapped
Draft

fix(InputHandler): isWrapped correctness after erase and column ops#5995
Tyriar wants to merge 3 commits into
masterfrom
fix/inputhandler-iswrapped

Conversation

@Tyriar

@Tyriar Tyriar commented Jun 3, 2026

Copy link
Copy Markdown
Member

Summary

Keeps soft-wrap chain integrity after erase sequences and scroll-margin column operations.

Changes

  1. ED Ps=1 — When clearing wrap on the line below the cursor at end-of-line, use ybase + j + 1 instead of lines.get(j + 1) so scrollback does not point at the wrong buffer line.
  2. EL Ps=1 — Mirror ED when a full line is erased at the last column; clear isWrapped on the following line (with unit test).
  3. Column ops — After scrollLeft / scrollRight, insertColumns, and deleteColumns, call new _clearWrapBelowScrollMargins() to clear stale wrap on the first line below the bottom scroll margin.

Repro ideas

  • Scrollback present + ED 1 at EOL on a wrapped row.
  • EL 1 at last column on a line that continues a wrap on the next row.
  • Wrapped line spanning the bottom margin + DECSTBM + DECIC / DECDC / SL / SR.

Risk

Touches CSI erase and margin column behavior. Spec ambiguity: whether clearing wrap below the margin is always required vs. only when the margin line was part of a wrap chain—current approach matches xterm-style conservative clearing (same spirit as existing in-margin isWrapped = false).

Commits (cherry-picked from tyriar/explore-correctness)

  • 0383787 — ED Ps=1: ybase when clearing wrap on line below cursor at EOL
  • b679cdc — EL Ps=1: same wrap clear at last column (+ unit test)
  • 32ef836 — scroll L/R, insert/delete columns: clear wrap below scroll bottom margin
Open in Web Open in Cursor 

Tyriar and others added 3 commits June 3, 2026 03:36
eraseInDisplay Ps=1 clears from the start of the viewport through the
cursor. When the cursor is in the last column, the following line's
isWrapped flag must be cleared because the erased line can no longer
continue a wrapped row.

_eraseInBufferLine already addresses buffer lines with ybase + y, but
the next-line lookup used lines.get(j + 1) without ybase. With
scrollback (ybase > 0), that touched the wrong line and left incorrect
wrap state on the line below the cursor.

Co-authored-by: Cursor <cursoragent@cursor.com>
CSI EL Ps=1 erases from the start of the row through the cursor.
When the cursor is in the last column, that clears the entire row but
did not clear isWrapped on the following line. eraseInDisplay Ps=1
already handled this case with ybase-aware indexing.

Mirror that behavior in eraseInLine so soft-wrap chains stay
consistent after erase-to-left at end of line.

Co-authored-by: Cursor <cursoragent@cursor.com>
scrollLeft, scrollRight, insertColumns, and deleteColumns set
isWrapped=false on every line inside the scroll margins but left
the first line below scrollBottom unchanged. A soft wrap spanning
the bottom margin and the next row could leave a stale isWrapped
flag on the line below, breaking wrapped string translation.

Clear isWrapped on the buffer line below the bottom margin after
each of these column operations.

Co-authored-by: Cursor <cursoragent@cursor.com>
@PerBothner

Copy link
Copy Markdown
Contributor

Note the first 2 commits are also handled by PR #5785.

I don't believe the current PR goes far enough. It does not seem to fix EL Ps=0 or EL Ps=2, which should also clear the wrapped flag on the following line. PR #5785 fixes those by moving the clearing into _eraseInBufferLine.

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.

2 participants