[codex] Persist terminal highlights across scrolling - #2348
Open
mam15mon wants to merge 12 commits into
Open
Conversation
added 12 commits
July 21, 2026 11:11
Contributor
Author
|
@codex review |
cursor Bot
pushed a commit
that referenced
this pull request
Aug 7, 2026
Replace Enter scroll-skip band-aid with mam15mon/#2348 persistence: keep decorations across scroll, sync only newly exposed rows, bound retention (~20 viewports / max 1200). Keep Enter write-path protections and cursor-line atomic swap. Continuous Enter may scroll; prune-on-scroll is gone. Co-authored-by: mam15mon <mam15mon@users.noreply.github.com> Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com>
14 tasks
Contributor
|
感谢 @mam15mon 的方案。 我们在 #2805(修 #2784)里手工移植了本 PR 的核心模型:滚动时保留附近关键词高亮、只扫新露出行、并对持久 decoration 做视口/行数上限,而不是用 Enter 特判去跳过 scroll prune。连续回车会真实滚动,因此「滚动保留高亮」比 Enter 特判更合适。 因 main 上 若维护者认同,可将本 PR 标为 superseded by #2805 后关闭。 |
cursor Bot
pushed a commit
that referenced
this pull request
Aug 7, 2026
* fix(terminal): stop keyword highlight flicker on Enter Idle Enter was misclassified as user scroll so overscan decorations were pruned before writeParsed cancel (Ubuntu RTT). Also swap cursor-line decorations atomically to avoid clear-before-create flash (fixes #2784). Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com> * fix(terminal): catch up highlights after Enter protection window While enterInputPending blocked scroll-prune, viewport scrolls were also ignored with no dirty mark. Mark dirty during the window and trigger a write refresh when Enter protection clears. Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com> * fix(terminal): persist keyword highlights across scroll (#2784) Replace Enter scroll-skip band-aid with mam15mon/#2348 persistence: keep decorations across scroll, sync only newly exposed rows, bound retention (~20 viewports / max 1200). Keep Enter write-path protections and cursor-line atomic swap. Continuous Enter may scroll; prune-on-scroll is gone. Co-authored-by: mam15mon <mam15mon@users.noreply.github.com> Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com> * fix(terminal): bound persistent keyword prune to scroll path Keep Enter/write deferred pruning intact by pruning the retention cap only after scroll viewport indexing, not on every decoration apply. Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com> * fix(terminal): rescan dirty overlap on persistent scroll refresh Overlapping scroll only scanned newly exposed rows then cleared the whole viewport dirty set, which could drop in-place redraw work when scroll outranked a pending write refresh. Rescan write-dirtied overlap lines and only clear dirty for ranges that were actually processed. Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com> Co-authored-by: mam15mon <mam15mon@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Root cause
The current user-scroll path intentionally waits 120 ms, scans only the settled viewport, and then deletes decorations outside that viewport. This makes unhighlighted text visible before the delayed decoration refresh. Restoring the old full-window synchronous rebuild would bring back scroll jank because it rescanned roughly five viewports on every scroll event.
Behavior
User scrolling now reuses the contiguous indexed range and scans only newly exposed rows. A distant jump scans one viewport synchronously in xterm's
onScrollcallback, before xterm queues its own refresh. Output-driven scrolling, large-output quiet windows, recent-input protection, long-line safeguards, and alternate-buffer behavior remain unchanged.Validation
npm run lint(0 errors; 4 pre-existing warnings outside this change)node --test --import tsx components/terminal/keywordHighlight.test.ts components/terminal/keywordHighlightRegex.test.ts components/terminal/runtime/terminalOutputPressure.test.ts(31 passed)git diff upstream/main...HEAD --checkRegression coverage includes preindexed scrolling, distant jumps, continuous jumps, scrolling during write bursts, marker disposal and reset, uniform scrollback shifts, constant-time marker lookup, bounded broad-rule retention, ANSI in-place redraws, large output, recent input, and oversized wrapped lines.