|
| 1 | +#!/usr/bin/env python |
| 2 | +""" |
| 3 | +Interactive checklist for Kitty-only key gestures. |
| 4 | +
|
| 5 | +prompt_toolkit pushes the Kitty keyboard protocol (flag 1) on startup, |
| 6 | +so terminals that implement it (kitty, ghostty, wezterm, foot, |
| 7 | +Alacritty, recent iTerm2 with CSI u reporting enabled, …) can |
| 8 | +distinguish modifier+Enter, modifier+Tab, modifier+Escape, and |
| 9 | +modifier+Backspace combinations that collapse to a single byte on |
| 10 | +legacy terminals. |
| 11 | +
|
| 12 | +The bottom toolbar lists every such gesture. Press one and its row |
| 13 | +turns green. On terminals without the protocol, rows stay grey — |
| 14 | +that's the expected fallback, not a bug. Press plain Enter to exit. |
| 15 | +""" |
| 16 | + |
| 17 | +from prompt_toolkit import prompt |
| 18 | +from prompt_toolkit.key_binding import KeyBindings |
| 19 | +from prompt_toolkit.styles import Style |
| 20 | + |
| 21 | +KITTY_KEYS: list[tuple[str, str]] = [ |
| 22 | + ("c-enter", "Ctrl-Enter"), |
| 23 | + ("s-enter", "Shift-Enter"), |
| 24 | + ("c-s-enter", "Ctrl-Shift-Enter"), |
| 25 | + ("c-tab", "Ctrl-Tab"), |
| 26 | + ("c-s-tab", "Ctrl-Shift-Tab"), |
| 27 | + ("c-escape", "Ctrl-Escape"), |
| 28 | + ("c-s-escape", "Ctrl-Shift-Escape"), |
| 29 | + ("c-backspace", "Ctrl-Backspace"), |
| 30 | + ("s-backspace", "Shift-Backspace"), |
| 31 | + ("c-s-backspace", "Ctrl-Shift-Backspace"), |
| 32 | +] |
| 33 | + |
| 34 | + |
| 35 | +def main(): |
| 36 | + pressed: set[str] = set() |
| 37 | + |
| 38 | + def toolbar(): |
| 39 | + lines = [("", "Kitty-only gestures — press each to turn it green:\n")] |
| 40 | + for binding, label in KITTY_KEYS: |
| 41 | + if binding in pressed: |
| 42 | + lines.append(("class:done", f" [x] {label}\n")) |
| 43 | + else: |
| 44 | + lines.append(("class:todo", f" [ ] {label}\n")) |
| 45 | + remaining = len(KITTY_KEYS) - len(pressed) |
| 46 | + if remaining: |
| 47 | + lines.append(("", f"\n{remaining} remaining — plain Enter to exit.")) |
| 48 | + else: |
| 49 | + lines.append(("class:done", "\nAll gestures recorded. Enter to exit.")) |
| 50 | + return lines |
| 51 | + |
| 52 | + bindings = KeyBindings() |
| 53 | + |
| 54 | + def make_handler(binding: str): |
| 55 | + def handler(event): |
| 56 | + pressed.add(binding) |
| 57 | + event.app.invalidate() |
| 58 | + |
| 59 | + return handler |
| 60 | + |
| 61 | + for binding, _label in KITTY_KEYS: |
| 62 | + bindings.add(binding)(make_handler(binding)) |
| 63 | + |
| 64 | + style = Style.from_dict( |
| 65 | + { |
| 66 | + "bottom-toolbar": "noreverse", |
| 67 | + "bottom-toolbar.text": "", |
| 68 | + "done": "fg:ansigreen bold", |
| 69 | + "todo": "fg:ansibrightblack", |
| 70 | + } |
| 71 | + ) |
| 72 | + |
| 73 | + prompt( |
| 74 | + "> ", |
| 75 | + bottom_toolbar=toolbar, |
| 76 | + key_bindings=bindings, |
| 77 | + style=style, |
| 78 | + refresh_interval=0.5, |
| 79 | + ) |
| 80 | + |
| 81 | + |
| 82 | +if __name__ == "__main__": |
| 83 | + main() |
0 commit comments