No description
  • Python 97.4%
  • Nix 2.6%
Find a file
Antoine Vaure d383791fad
All checks were successful
ci-tron/test Success
Preserve original colors/formatting in selection mode
Capture styled text (as_ansi=True) and render it as the base layer;
model.py keeps operating on plain text via a new ansi.unstyled() helper,
with selection/search highlighting punched in as a separate overwrite.
2026-09-07 16:09:24 +02:00
tests Preserve original colors/formatting in selection mode 2026-09-07 16:09:24 +02:00
.ci-tron.json Initial implementation: reproduce st's keyboard-select mode as a kitty kitten 2026-09-07 14:44:53 +02:00
.gitignore Initial implementation: reproduce st's keyboard-select mode as a kitty kitten 2026-09-07 14:44:53 +02:00
AGENTS.md Preserve original colors/formatting in selection mode 2026-09-07 16:09:24 +02:00
ansi.py Preserve original colors/formatting in selection mode 2026-09-07 16:09:24 +02:00
CLAUDE.md Initial implementation: reproduce st's keyboard-select mode as a kitty kitten 2026-09-07 14:44:53 +02:00
conftest.py Initial implementation: reproduce st's keyboard-select mode as a kitty kitten 2026-09-07 14:44:53 +02:00
flake.lock Initial implementation: reproduce st's keyboard-select mode as a kitty kitten 2026-09-07 14:44:53 +02:00
flake.nix Preserve original colors/formatting in selection mode 2026-09-07 16:09:24 +02:00
grab.py Preserve original colors/formatting in selection mode 2026-09-07 16:09:24 +02:00
keymap.py Initial implementation: reproduce st's keyboard-select mode as a kitty kitten 2026-09-07 14:44:53 +02:00
model.py Initial implementation: reproduce st's keyboard-select mode as a kitty kitten 2026-09-07 14:44:53 +02:00
README.md Preserve original colors/formatting in selection mode 2026-09-07 16:09:24 +02:00
ROADMAP.md Initial implementation: reproduce st's keyboard-select mode as a kitty kitten 2026-09-07 14:44:53 +02:00
ui.py Preserve original colors/formatting in selection mode 2026-09-07 16:09:24 +02:00

pounce

A kitty kitten that reproduces st's KEYBOARDSELECT_PATCH (reflow variant) keyboard-driven text selection mode, keybind-for-keybind, so muscle memory carries over between the two terminals.

Bind it in kitty.conf:

map ctrl+shift+space kitten pounce/grab.py
map ctrl+shift+f     kitten pounce/grab.py --search=forward
map ctrl+shift+b     kitten pounce/grab.py --search=backward

(pounce/ here is wherever you install this kitten's five files under ~/.config/kitty/; see flake.nix's packages.default for a Nix-built install.)

Layout

  • model.py — the entire selection/movement/search state machine, in plain Python with no kitty.* imports. Fully unit-tested (tests/).
  • keymap.py — declarative table mapping key presses to the abstract commands model.py understands. Also plain Python, also tested.
  • ansi.py — strips ANSI escape sequences from captured terminal text. Also plain Python, also tested. model.py only ever sees the stripped (plain) text; ui.py renders the original styled text underneath its own selection/search highlighting, so colors and formatting survive into selection mode.
  • grab.py / ui.py — the kitty-specific glue: capturing the terminal's screen and scrollback, driving model.py from real key events, and rendering. This part isn't covered by the test suite (it needs a real kitty process) and should stay as thin as possible — new behavior belongs in model.py, not here.

Known fidelity gap

st's Return copies the selection to the clipboard and leaves it highlighted in the terminal after exiting keyboard-select mode, because the selection is part of st's own persistent terminal state. This kitten's selection only exists for the lifetime of its overlay process, drawn over a static snapshot of the screen — once that process exits there is no live terminal state left to keep highlighted (kitty gives kittens no way to inject a persistent selection into a real window). Return here copies and exits, without the lingering highlight.

Testing

nix develop .#ci --command pytest

CI (ci-tron, see .ci-tron.json) runs the same command on every push.