fzf consumed only the part of a sequence it recognized, and the rest was
typed into the query. CTRL-A sent as \e[97;5u became "97;5u". A
BEL-terminated OSC reply also aborted fzf, because the BEL that followed
the typed payload was read as CTRL-G.
Frame CSI and SS3 by their parameter and final byte ranges, OSC, DCS and APC
by their terminator, then drop the whole sequence when nothing matches it.
The second-chance read now runs only while a sequence is unfinished, since
after a complete one it blocked until the next keystroke.
Telling a terminal's sequence from an ALT key is the hard part, so several
shapes are deliberately left alone:
- An unterminated sequence, since that is how ALT-[, ALT-O, ALT-], ALT-P and
ALT-_ arrive, and an empty one for the same reason
- A CSI or SS3 short enough to be an ALT key with one or two characters typed
after it
- SOS and PM, which nothing sends, so ALT-X and ALT-^ are not delayed
- An ESC inside a string, which ends it and introduces a sequence of its
own, so scanning on to a later ST would swallow that one
- Only OSC ends with BEL. DCS and APC end with ST, and stopping at a BEL in
their payload framed just its first half
The read loop does not wait for a string terminator either. Waiting held
ALT-], ALT-P and ALT-_ for ESCDELAY and let typed bytes pile into the buffer
until they looked like a sequence, which swallowed a CTRL-G abort.
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