Keep rxvt keys intact when checking the frame

- Leave a short frame the parser rejects as it was. rxvt sends keys of that
  size fzf does not know, such as \e[3^ for CTRL-DELETE, and reporting them
  as ALT-[ typed "3^" into the query
- Do not widen a parse that ends in an intermediate byte. rxvt ends keys with
  $, as in \e[7$ for SHIFT-HOME, and widening took the next typed key with it
This commit is contained in:
Junegunn Choi committed 2026-10-03 15:06:08 +09:00
1 parent c2cee734f4
commit 9c603bedb3
2 files changed
+18 -13

No files matched your search

+8 -9
View File
@@ -348,6 +348,8 @@ func getEnv(name string, defaultValue int) int {
func csiContinues(b byte) bool { return b >= 0x20 && b <= 0x3f }
func csiFinal(b byte) bool { return b >= 0x40 && b <= 0x7e }
func csiIntermediate(b byte) bool { return b >= 0x20 && b <= 0x2f }
// csiEnd returns the length of the CSI sequence at the start of the buffer, or
// 0 if it has no final byte yet or is malformed.
func csiEnd(buffer []byte) int {
@@ -645,18 +647,15 @@ func (r *LightRenderer) escSequence(sz *int) Event {
if end == 0 {
return ev
}
// The same rule as the fall-through: four bytes or fewer could be ALT-[
// or ALT-O and typed text
// Four bytes or fewer could be ALT-[ or ALT-O and typed text, and rxvt sends
// keys of that size fzf does not know, such as \e[3^ for CTRL-DELETE
if end <= 4 {
if ev.Type == Invalid {
*sz = 2
return AltKey(rune(r.buffer[1]))
}
return ev
}
// A key matched on a prefix, such as Home for \e[70;5u, or a sequence
// given up on partway
if end > *sz {
// A key matched on a prefix, such as Home for \e[70;5u, or a sequence given
// up on partway. rxvt ends keys with the intermediate byte $, as in \e[7$
// for SHIFT-HOME, so a parse ending there is complete.
if end > *sz && !csiIntermediate(r.buffer[*sz-1]) {
*sz = end
return Event{Invalid, 0, nil}
}
+10 -4
View File
@@ -49,10 +49,16 @@ func TestUnknownEscapeSequence(t *testing.T) {
{"\x1b[ x", Alt, 2},
{"\x1bOx", Alt, 2},
{"\x1bO9A", Alt, 2},
{"\x1b[2m", Alt, 2}, // the parser gives up on these itself
{"\x1b[3x", Alt, 2},
{"\x1b[<a", Alt, 2},
{"\x1bO<a", Alt, 2},
// rxvt keys fzf does not know: dropped, not typed
{"\x1b[3^", Invalid, 4}, // CTRL-DELETE
{"\x1b[5^", Invalid, 4}, // CTRL-PAGEUP
{"\x1b[3@", Invalid, 4}, // CTRL-SHIFT-DELETE
{"\x1b[11^", Invalid, 5},
// rxvt ends keys with $, so a key typed after one is not part of it
{"\x1b[7$x", Home, 4}, // SHIFT-HOME, then x
{"\x1b[3$x", Invalid, 4},
{"\x1b]abc", Alt, 2},
{"\x1b]11;rgb:", Alt, 2}, // terminator has not arrived
{"\x1b]\x1b]", Alt, 2}, // a second sequence must not swallow the ALT key