feat(tui): configurable key bindings system #50
No reviewers
Labels
No labels
area:agents
area:ai
area:config
area:dashboard
area:design
area:design-review
area:devtools
area:entities
area:gallery
area:generate
area:image
area:infra
area:meta
area:model-browser
area:navigation
area:presets
area:security
area:sessions
area:settings
area:sharing
area:test
area:ux
area:webhook
area:workdir
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/loom!50
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "tui/keybinds-19"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Third PR in the loom-tui stack. Adds a real key-binding layer so the spec §3.1 defaults come from data instead of hard-coded matches, and future config loading can layer overrides.
Stacks on #49. Closes charles/loom#19.
What's in
KeyCombo— single modified key press with round-trippableDisplay/FromStr. HandlesCtrl+Shift+K,Esc,?,F5,Space, lowercase modifiers, shift normalisation for printable charsBinding—Single(KeyCombo)orChord(KeyCombo, KeyCombo); also round-trippable ("g g")KeyMap— scope-aware lookup (Scope::GlobalvsScope::Screen(ScreenKind)), per-screen shadows global,apply_overrides(toml::Table, known_action_ids)withOverrideWarnings (UnknownAction,BadValue,ParseError)ChordTracker— state machine that walks keystrokes and returnsAction(id)/Pending/Unbound. Prefers holding when a key is a chord prefix in the active scope so chords are always reachableactionsmodule —APP_*andNAV_*action id constants. Screen-local action ids get added alongside their screensdefaults()— compiles the spec §3.1 global map inApprefactor — the old hard-coded match block is gone.handle_global_keyroutes throughChordTracker::step→invoke_action(ActionId). Chord state resets on navigation.Tests (16 total, all passing)
UnknownModifier"g g"→Chord)gwhen aggchord is scoped to the current screen, then fires chord on secondgUnknownActionwarning for bogus idsNotes
Binding::single / chord,KeyMap::unbind,apply_overrides,known_action_idsare#[allow(dead_code)]— they're the consumer surface for #43 (config) and #39 (settings editor). Marked explicitly so accidental dead code elsewhere still warnsAPP_TOGGLE_SIDEBAR/APP_FOCUS_NEXT/APP_FOCUS_PREV/APP_PALETTEactions are parsed into the defaults butinvoke_actiononly handles quit/help/cancel/nav today. The rest come online in #17 (sidebar/focus), #18 (palette)