feat(keys): configurable vim-style keybindings - #59
Merged
Merged
Conversation
Add keyboard shortcuts to the modal, driven by a keymap that users can customize in `~/.config/aura/keybindings.toml` and manage from the CLI. Keymap (aura-core `keymap`): - Action catalogue (scroll, navigate, commands) and vim-style defaults: j/k, ctrl-d/u, ctrl-f/b, gg/G, h/l + tab + gt/gT, 1-9, H/L + [/], m, p/P, r, `,`, `.`, `?`, q, esc. - `[global]` and `[overlay]` contexts, `"none"` to unbind, and `use_defaults = false` to start from an empty keymap. - Loading never fails. Bad entries are skipped with warnings: invalid TOML, unknown table or action (with a "did you mean"), bad keystroke, non-string value, duplicate spellings (`G` / `shift-g`), no-op unbinds, prefix conflicts (`g` vs `g g`), and bindings that take over the text-selection keys (ctrl-c, ctrl-a, shift+arrows). - `KeymapFile`: format-preserving edits via toml_edit (bind, remove, clear, set_action_keys, restore_action, merge, document), so CLI writes keep the user's comments and layout. Modal: - The root element holds a FocusHandle and the `Aura` / `overlay` key contexts; one GPUI action per KeyAction, wired exhaustively. - Escape clears a selection, then closes the open overlay, then closes the window. `q` closes the window. `quit` is available but unbound. - `?` opens a help overlay generated from the live keymap, with any keymap warnings at the top. A header chip shows the warning count, and settings gains a Keybindings entry. - The keymap is reloaded on every open and every refresh. - `[keybindings] enabled` in config.toml (default true) turns every shortcut off; the existing Escape observer covers that case. CLI (`aura keys`, alias `aura keybindings`): - path, list, describe (actions or a keystroke), get, set, unbind, reset (keys / --action / --all), wizard, merge (--prefer, --check, stdin), export, init (--full), document, validate, edit. - `aura doctor` reports the keybindings file and its warnings. - Restore default SIGPIPE for CLI runs, so `aura … | head` exits quietly instead of panicking. Docs: new docs/keybindings.md; configuration.md, cli.md and the README updated.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds keyboard shortcuts to the modal: vim-style defaults, a user override file (
~/.config/aura/keybindings.toml) with warnings for bad entries, a master switch inconfig.toml, and anaura keysCLI that mirrorsaura config.Keymap
Defaults:
j/k,ctrl-d/ctrl-u,ctrl-f/ctrl-b,g g/Gh/l,tab,g t/g T,1–9H/L,[/]mp/Pr,.?qescContexts:
[global]applies everywhere.[overlay]applies while a menu, the settings panel or the help is open, and wins over[global]for the same keys.Overrides:
"none"unbinds a key.use_defaults = falsestarts from an empty keymap.Loading never fails. A bad entry is skipped with a warning; the rest still applies. Aura warns about:
G/shift-g)galongsideg g)Where warnings show up: a header chip with the count, the top of the
?help overlay, stderr (once per distinct set),aura keys validate(exits 1), andaura doctor.Off switch:
[keybindings] enabled = falseinconfig.tomlturns every shortcut off. Escape still closes the window.Reloading: the keymap is re-read on every open and every refresh, with no restart needed.
CLI:
aura keys(aliasaura keybindings)pathlist [--context]describe [action|keys]get <keys>set <keys> <action>/unbind <keys>reset <keys>,--action,--allwizardmerge <file|->--prefer theirs|ours,--checkexportinit [--full]documentvalidateedit$EDITORRead commands take
--format json. The write commands go throughKeymapFile, which edits withtoml_edit, so they keep the user's comments and layout.Implementation notes
aura-core/src/keymap/holds the parser, defaults, merge logic and warnings (mod.rs) and the file editor (file.rs). Neither has any UI code; the CLI and the modal share them.aura/src/keys.rsdefines one GPUI action perKeyAction, wired through an exhaustive match so an unwired action won't compile.FocusHandle, because GPUI dispatches bindings only from a focused element. This reverses the "no focus handles" note indocs/plans/selectable-text.md. Nothing else in the modal is focusable, and a click anywhere puts focus back on the root.[global]and[overlay]are key contexts on the same root element, so GPUI can't rank them by depth and falls back to insertion order. Overlay bindings are therefore installed last.toml_editdependency in aura-core. It was already in the lockfile transitively, so nothing new is downloaded.aura … | headexits quietly instead of panicking.Testing
cargo clippy --workspace --all-targets -D warnings,cargo fmt --checkandcargo test --workspacepass. There are 24 new keymap unit tests: parsing, merge, warnings, and the file editor (format preservation, wizard key-set semantics, merge, document, export round-trip).aura keyscommand was tried by hand against separate test config directories.?,Gandshift-tabmatch on non-US keyboard layoutsDocs:
docs/keybindings.md(new), plus updates todocs/configuration.md,docs/cli.mdand the README.