Skip to content

Wait for rest of escape sequence before parsing - #4901

Merged
junegunn merged 2 commits into
masterfrom
escape-fragment-wait
Aug 23, 2026
Merged

Wait for rest of escape sequence before parsing#4901
junegunn merged 2 commits into
masterfrom
escape-fragment-wait

Conversation

@junegunn

Copy link
Copy Markdown
Owner

Fix #4899

Contribution Policy

We do not accept pull requests generated primarily by AI without genuine understanding or real-world usage context.

All contributions are expected to demonstrate:

  • A clear understanding of the codebase
  • Alignment with product direction
  • Thoughtful reasoning behind changes
  • Evidence of real-world usage or hands-on experience with the problem

If these expectations are not met, we would prefer to implement the changes ourselves rather than spend time reviewing low-effort submissions.


Acknowledgement

  • I confirm that this PR meets the above expectations and reflects my own understanding and real-world context.

Read loop dropped its escDelay retry budget after every successful byte,
so a sequence split across reads reached the parser as a fragment, parsed
as ALT-[ with the remainder left behind as query text.

- fzf queries DECRQM at startup since dab626b, so a terminal answering
  late leaked "?2004;2$y" into the query
- Same split leaked modified keys and mouse sequences: CTRL-UP left "5A",
  SGR mouse left "0;1;1M"
- Bound unchanged, a stall longer than escDelay still falls back to ALT

Fix #4899
@junegunn junegunn self-assigned this Aug 23, 2026
@github-actions github-actions Bot added go Go code test Tests labels Aug 23, 2026
@junegunn
junegunn requested a lite review from Copilot August 23, 2026 12:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

incompleteEscape is invoked per-byte and currently scans the full buffer, creating O(n^2) behavior during large reads (e.g. paste), which is a likely performance regression.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR adjusts the TUI input read loop to avoid handing partial ANSI escape sequences to the parser by extending the escape-delay window while a CSI/SS3 sequence is still incomplete, addressing the regression reported in #4899.

Changes:

  • Add CSI framing helpers and incompleteEscape detection to decide when to keep waiting for more bytes.
  • Update getBytesInternal to refresh the escape-delay “budget” while an escape sequence is still arriving.
  • Add unit tests covering complete vs. incomplete escape-sequence buffering behavior.
File summaries
File Description
src/tui/light.go Adds escape-sequence continuation detection and updates the read loop to wait for completion.
src/tui/light_escape_test.go Adds tests for incompleteEscape to ensure correct waiting behavior.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/tui/light.go
incompleteEscape runs once per byte read and scanned the whole buffer
back to the last ESC, so a paste that accumulates in one read made input
handling quadratic. 256KB paste took 15.3s against 3.8s before.

- Scan only the last 256 bytes, well past any sequence fzf parses
- Sequence longer than that is not waited for, same as before this branch
- Window size does not affect throughput, 64 and 1024 measure the same

Reported by Copilot on #4901

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The change is narrowly scoped, includes targeted tests, and directly prevents partial escape-sequence parsing that can leak terminal replies into the prompt.

Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@junegunn
junegunn merged commit d0377ed into master Aug 23, 2026
7 checks passed
@junegunn
junegunn deleted the escape-fragment-wait branch August 23, 2026 15:40
hmr pushed a commit to hmr/fzf-hmr that referenced this pull request Aug 25, 2026
Read loop dropped its escDelay retry budget after every successful byte,
so a sequence split across reads reached the parser as a fragment, parsed
as ALT-[ with the remainder left behind as query text.

- fzf queries DECRQM at startup since dab626b, so a terminal answering
  late leaked "?2004;2$y" into the query
- Same split leaked modified keys and mouse sequences: CTRL-UP left "5A",
  SGR mouse left "0;1;1M"
- Bound unchanged, a stall longer than escDelay still falls back to ALT

Fix junegunn#4899
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

go Go code test Tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Invoking fzf in alacritty with overriden conpty.dll *sometimes* puts ?2004;2$y into the prompt.

2 participants