pi-mono/packages/tui/test
robopipi[bot] deb12d78eb
fix(tui): recognize kitty F1-F12 sequences and ignore F13+ keys (#11468)
With the kitty keyboard protocol active, these function keys were not
recognized:
- F1, F2 and F4 arrive as `CSI P`/`Q`/`S`, or as `CSI 1;<mod> P/Q/S`.
- Any F-key pressed with a modifier, e.g. `CSI 15;5~` for Ctrl+F5.

`matchesKey` returned false whenever a modifier was set and only
compared against the legacy sequences. `parseKittySequence` did not know
any F-key forms. So shortcuts bound to keys like `f1` or `ctrl+f5` never
fired.

Separately, F13–F35 (and other kitty functional keys) arrive as CSI-u
codepoints in the Private Use Area. `decodeKittyPrintable` returned them
as text, so the editor inserted invisible U+E020+ characters into the
prompt.

Changes in `packages/tui/src/keys.ts`:
- Add F1–F12 internal codepoints. Map `~` numbers 11–15, 17–21, 23 and
24 to them.
- Parse the `CSI [1;mod[:event]] P/Q/S` form. F3 is left out because
`CSI 1;<n>R` collides with cursor position reports, so kitty sends F3 as
`CSI 13~`.
- Let the `f1`…`f12` cases in `matchesKey` fall back to
`matchesKittySequence` so modifiers work. Name the keys in `parseKey`
output.
- Make `isKeyRelease` and `isKeyRepeat` recognize `:3`/`:2` events on
P/Q/S, so F1/F2/F4 releases don't trigger shortcuts a second time.
- `decodeKittyPrintable` now rejects the kitty functional-key PUA range
(57344–63743). Keypad keys are normalized to ASCII first, so they still
decode.

Testing:
- Added tests in `packages/tui/test/keys.test.ts`. They cover kitty
F1–F12 with and without modifiers, F3 not being confused with a cursor
position report, release and repeat detection, and F13+ not decoding as
text. Two of the new tests fail without the change; all pass with it.
- Ran `npm test` in `packages/tui` and `npm run check`; both pass.
- Before the change: `parseKey("\x1b[P")` and `parseKey("\x1b[1;5P")`
returned `undefined`, `matchesKey("\x1b[15;5~", "ctrl+f5")` returned
false, and `decodePrintableKey("\x1b[57376u")` returned `"\ue020"`.
- After the change: these give `f1`, `ctrl+f1`, true and `undefined`.

Fixes #11419
Fixes #11345

Requested by @badlogic

Co-authored-by: triagent <triagent@localhost>
2026-10-27 09:16:36 +01:00
..
fixtures fix(tui): restore terminal modes when the process exits without stop() 2026-10-20 19:52:54 +02:00
alt-screen-large-transcript-bench.ts feat(tui,coding-agent): report program status via OSC 7501 2026-10-07 19:05:41 +00:00
autocomplete-skill-slash.test.ts fix(tui): complete slash commands after leading whitespace (#10218) 2026-09-30 23:13:01 +02:00
autocomplete.test.ts fix(tui): escape regex metacharacters in single-segment fd queries (#11212) 2026-10-21 12:21:15 +02:00
bug-regression-isimageline-startswith-bug.test.ts chore: pin dependencies and use native TypeScript 2026-05-20 12:46:17 +02:00
chat-simple.ts fix(tui): normalize source filenames 2026-08-01 14:38:13 +02:00
colors.test.ts feat(coding-agent,tui): System theme (#10067) 2026-09-26 13:33:47 +02:00
editor-history-keybindings.test.ts feat(tui): add configurable prompt history actions 2026-08-05 21:34:21 +02:00
editor.test.ts feat(tui,coding-agent): use only the terminal cursor when showHardwareCursor is enabled 2026-10-08 00:23:06 +02:00
exit-restore.test.ts fix(tui): restore terminal modes when the process exits without stop() 2026-10-20 19:52:54 +02:00
fuzzy.test.ts fix(tui,coding-agent): rank contiguous fuzzy matches and search session fields separately 2026-10-22 21:39:17 +02:00
image-test.ts feat: build with TypeScript 7 and run sources with plain node 2026-09-25 13:14:33 +02:00
input.test.ts feat(tui): search improvements (#8800) 2026-09-03 15:09:51 +02:00
key-tester.ts fix(tui): normalize source filenames 2026-08-01 14:38:13 +02:00
keybindings.test.ts fix(tui): keep Home/End for the editor in fullscreen mode 2026-10-05 09:53:54 +02:00
keys.test.ts fix(tui): recognize kitty F1-F12 sequences and ignore F13+ keys (#11468) 2026-10-27 09:16:36 +01:00
latex.test.ts fix(tui): improve LaTeX compatibility and layouts 2026-09-19 23:28:04 +02:00
layout.test.ts feat(tui): alt mode scrollbar but prettier (#8801) 2026-09-04 00:05:47 +02:00
markdown.test.ts fix(tui): stop nested blockquote rendering from growing exponentially (#11321) 2026-10-23 12:46:03 +02:00
mouse-components.test.ts feat(coding-agent,tui): System theme (#10067) 2026-09-26 13:33:47 +02:00
native-clipboard-linux.test.ts feat(tui): Simplify clipboard handling (#9163) 2026-09-05 23:52:32 +02:00
native-module-path.test.ts feat(tui): Simplify clipboard handling (#9163) 2026-09-05 23:52:32 +02:00
native-platform.test.ts feat(tui): Simplify clipboard handling (#9163) 2026-09-05 23:52:32 +02:00
overlay-non-capturing.test.ts fix(tui): normalize source filenames 2026-08-01 14:38:13 +02:00
overlay-options.test.ts fix(tui): keep cursor visible when overlays close after stop 2026-09-25 13:30:50 +02:00
overlay-short-content.test.ts fix(tui): normalize source filenames 2026-08-01 14:38:13 +02:00
program-status.test.ts feat(tui,coding-agent): report program status via OSC 7501 2026-10-07 19:05:41 +00:00
regression-overlay-cjk-boundary.test.ts feat(tui): add alternate-screen renderer 2026-07-30 12:59:48 +02:00
regression-regional-indicator-width.test.ts chore: pin dependencies and use native TypeScript 2026-05-20 12:46:17 +02:00
regression-sigwinch-kill-eacces.test.ts fix(tui): wrap SIGWINCH self-signal so restricted seccomp policies do not crash startup (#8898) 2026-09-01 14:16:21 +02:00
regression-slice-by-column-ansi-order.test.ts fix(tui): preserve ANSI order at slice boundaries 2026-10-01 00:05:28 +02:00
render-churn-bench.ts feat(tui,coding-agent): report program status via OSC 7501 2026-10-07 19:05:41 +00:00
select-list.test.ts chore: pin dependencies and use native TypeScript 2026-05-20 12:46:17 +02:00
settings-list.test.ts feat(coding-agent): rename UI mode to TUI mode 2026-08-05 22:56:58 +02:00
stdin-buffer.test.ts fix(tui): keep delayed terminal replies out of keyboard input 2026-10-11 20:17:00 +02:00
tab-width.test.ts fix(tui): normalize source filenames 2026-08-01 14:38:13 +02:00
terminal-colors.test.ts fix(tui): keep delayed terminal replies out of keyboard input 2026-10-11 20:17:00 +02:00
terminal-image.test.ts feat(tui): enable Kitty images for Rex 2026-10-20 18:54:36 +02:00
terminal.test.ts fix: harden handling of untrusted URLs, terminal text, and streamed data 2026-10-26 20:46:31 +01:00
test-themes.ts chore: pin dependencies and use native TypeScript 2026-05-20 12:46:17 +02:00
truncate-to-width.test.ts fix(tui): close truncated OSC 8 links (#7657) 2026-08-05 13:50:37 +02:00
truncated-text.test.ts chore: pin dependencies and use native TypeScript 2026-05-20 12:46:17 +02:00
tui-alt-screen.test.ts fix(tui): bound image line search by tallest registered image 2026-10-23 21:59:31 +02:00
tui-cell-size-input.test.ts fix(tui): normalize source filenames 2026-08-01 14:38:13 +02:00
tui-overlay-style-leak.test.ts fix(tui): normalize source filenames 2026-08-01 14:38:13 +02:00
tui-render.test.ts feat(tui,coding-agent): use only the terminal cursor when showHardwareCursor is enabled 2026-10-08 00:23:06 +02:00
tui-shrink.test.ts fix(tui): normalize source filenames 2026-08-01 14:38:13 +02:00
viewport-overwrite-repro.ts feat: build with TypeScript 7 and run sources with plain node 2026-09-25 13:14:33 +02:00
virtual-terminal.ts feat(tui,coding-agent): report program status via OSC 7501 2026-10-07 19:05:41 +00:00
visible-width.test.ts fix(tui,coding-agent): reduce render cost of theme changes and streaming 2026-09-29 08:23:46 +02:00
wheel-scroll.test.ts feat(tui,coding-agent): configurable fullscreen wheel scrolling with auto acceleration 2026-09-29 09:57:53 +02:00
word-navigation.test.ts fix(tui): align input word segmentation with editor (#5068) 2026-05-27 20:50:04 +02:00
wrap-ansi.test.ts fix(tui): handle CRLF and CR line endings (#6764) 2026-07-17 09:01:10 +02:00