Skip to content

fix(terminal): stop idle-Enter keyword highlight flash after #2880 hole - #2931

Merged
binaricat merged 5 commits into
mainfrom
cursor/issue-2879-31571007873
Aug 12, 2026
Merged

fix(terminal): stop idle-Enter keyword highlight flash after #2880 hole#2931
binaricat merged 5 commits into
mainfrom
cursor/issue-2879-31571007873

Conversation

@netcatty-bot

Copy link
Copy Markdown
Collaborator

Summary

  • Idle Enter at the bottom no longer takes the synchronous user-scroll highlight path when buffer length/baseY/cursor have not updated yet (Ubuntu RTT onScroll before dims change).
  • End / jump-back-to-bottom during the Enter guard still scans immediately, by tracking prior scrollback browsing instead of requiring an “output-driven” buffer delta.
  • Idle Enter suppresses keyword decoration dispose/apply until the Enter guard clears or a second write arrives, so prompt redraw (including custom ~/# rules) cannot force an xterm full-viewport repaint that flashes still-visible matches.
  • Sustained Enter output still clears the mute and continues multi-frame viewport scans as before.

Why

#2880 deferred bottom-pinned Enter scroll, then a follow-up required hasOutputDrivenViewportChange() so End stayed responsive. That gate reopened the flash: after an idle gap, Enter echo can scroll while the last snapshot still matches, so highlight treated it as a user scroll and rescanned. Separately, applying or disposing decorations on the new prompt line makes xterm repaint the whole viewport, which is what users see as existing keywords “闪” even when those decorations were never disposed.

Changes

  • components/terminal/keywordHighlight.ts: bottom Enter deferral uses wasBrowsingScrollback / return-to-bottom; idle Enter mutes decoration mutation; second write re-enables mutation without rewinding dirty ranges.
  • components/terminal/keywordHighlight.test.ts: coverage for scroll-before-buffer-dim update and idle prompt redraw; Enter redraw / full-refresh catch-up waits for the guard window.

Testing

  • node --test --import tsx components/terminal/keywordHighlight.test.ts (52 pass)
  • Manual (unverified here): Windows client → Ubuntu 24.04 SSH, keyword highlight on, custom ~/# rule optional, idle Enter — existing on-screen matches should not flash.

Fixes #2879

Automation

  • Automated implement pass
  • Review gate: @codex review (own/bot PRs only)
  • Draft until Codex reports clean findings

@netcatty-bot netcatty-bot added automation:bot-pr PR created or owned by Cursor automation automation:codex-loop Own/bot PR waiting on Codex review↔fix loop triage Touched by Cursor automation labels Aug 12, 2026
@binaricat

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cd12b04647

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread components/terminal/keywordHighlight.ts Outdated
Comment on lines +238 to +242
if (this.enterWriteParsedSeen) {
// Sustained Enter output: allow decoration catch-up so new matches
// are not postponed until the stream goes idle. Do not re-add the
// whole viewport dirty range — that rewinds multi-frame scans.
this.enterSuppressDecorationMutation = false;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep suppression across split prompt writes

When a single idle Enter's echo and prompt arrive in two onWriteParsed batches, the second callback reaches this branch and clears suppression even though both writes belong to the same idle submission. The queued scan then disposes or registers prompt-row decorations—for example with custom ~/# rules—causing the exact full-viewport repaint flash this change is intended to prevent. A second callback alone is not a reliable signal of sustained command output, so suppression should remain until an actual output/quiet criterion is met.

Useful? React with 👍 / 👎.

@binaricat

Copy link
Copy Markdown
Owner

@codex review

Repository owner deleted a comment from binaricat Aug 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9cd756f44b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread components/terminal/keywordHighlight.ts Outdated
Comment on lines +1143 to +1146
if (this.enterWriteParsedCount >= KeywordHighlighter.ENTER_SUPPRESS_LIFT_WRITE_COUNT) {
return true;
}
return this.isWriteBurstActive(performance.now());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep suppression through all prompt-write batches

When a prompt is emitted in three onWriteParsed batches—for example separate control-sequence, prompt-text, and mode-setting writes—this fixed callback threshold lifts suppression before the final prompt batch is scanned, allowing matching ~/# decorations to trigger the same full-viewport repaint. The fresh evidence in this revision is that the previous second-write trigger was replaced by an equally non-semantic third-write trigger; callback count still does not prove command output, so suppression should remain until an actual output or quiet criterion distinguishes the prompt.

Useful? React with 👍 / 👎.

@binaricat

Copy link
Copy Markdown
Owner

@codex review

Repository owner deleted a comment from binaricat Aug 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7408e960cc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +246 to +247
if (this.shouldLiftEnterDecorationSuppression()) {
this.enterSuppressDecorationMutation = false;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reset burst evidence for each Enter

When Enter follows another write burst within the burst-decay window, recentWriteBurst and lastWriteAt still describe the earlier output because the Enter handler does not reset them. A split echo/prompt can therefore make this predicate true on its second batch, lift suppression, and recreate the prompt-decoration viewport flash. The fresh evidence in this revision is that the new burst-based signal remains global rather than being scoped to writes observed after the current Enter.

Useful? React with 👍 / 👎.

Comment thread components/terminal/keywordHighlight.ts Outdated
Comment on lines +1143 to +1145
private shouldLiftEnterDecorationSuppression(): boolean {
if (!this.enterSuppressDecorationMutation) return false;
return this.isWriteBurstActive(performance.now());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow periodic refresh for slow command output

When a post-Enter command emits small writes every roughly 30–500 ms, updateWriteBurst() never reaches the six-write threshold because each interval exceeds 28 ms, while every callback rearms the 600 ms Enter guard. Consequently tail -f, progress output, and other steady but non-bursty commands can keep decoration mutation suppressed indefinitely, leaving new matches unhighlighted and removed matches stale until the stream pauses; the catch-up criterion needs to distinguish or periodically service these slower streams too.

Useful? React with 👍 / 👎.

@binaricat

Copy link
Copy Markdown
Owner

@codex review

Repository owner deleted a comment from binaricat Aug 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 60820acf9a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1632 to +1634
if (this.enterSuppressDecorationMutation) {
continue;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply highlights when users browse scrollback during Enter

When a user presses Enter and immediately scrolls to previously unindexed scrollback, the synchronous scroll refresh reaches this guard and skips every new decoration because Enter suppression is still active. processScrollViewport nevertheless records the range as covered, so matching lines remain visibly unhighlighted until the 600 ms Enter guard plus debounce expires; suppression should preserve existing prompt-area decorations without blocking decoration creation for a real scrollback browse.

Useful? React with 👍 / 👎.

@binaricat

Copy link
Copy Markdown
Owner

@codex review

Repository owner deleted a comment from binaricat Aug 12, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: d1cd072502

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@binaricat
binaricat marked this pull request as ready for review August 12, 2026 11:23
@binaricat
binaricat merged commit cfb5346 into main Aug 12, 2026
4 checks passed
@netcatty-bot netcatty-bot removed the automation:codex-loop Own/bot PR waiting on Codex review↔fix loop label Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automation:bot-pr PR created or owned by Cursor automation triage Touched by Cursor automation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 连接Ubuntu24.04lts的情况下,回车之后高亮的关键字还是会闪

2 participants