refactor(command): decouple keymap bindings from command implementations

Refactor the keymap system to use string-based command names instead of
concrete command struct instantiations. This introduces a Binding enum that
can represent either a command lookup (name + args) or a prefix sub-keymap.

Key changes:
- Keymap now stores Binding enum instead of Arc<dyn Cmd>
- dispatch() accepts CmdRegistry to resolve commands at runtime
- Added bind_args() for commands with arguments
- KeymapSet now owns the command registry
- Removed PrefixKey struct, inlined its logic
- Updated all default keymap bindings to use string names

This enables more flexible command configuration and easier testing.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
This commit is contained in:
Edward Langley
2026-04-04 11:02:00 -07:00
parent a45390b7a9
commit 649d80cb35
3 changed files with 267 additions and 358 deletions

View File

@ -1909,6 +1909,10 @@ pub fn default_registry() -> CmdRegistry {
"view-panel" => AppMode::ViewPanel,
"tile-select" => AppMode::TileSelect,
"command" => AppMode::CommandMode { buffer: String::new() },
"category-add" => AppMode::CategoryAdd { buffer: String::new() },
"editing" => AppMode::Editing { buffer: String::new() },
"formula-edit" => AppMode::FormulaEdit { buffer: String::new() },
"export-prompt" => AppMode::ExportPrompt { buffer: String::new() },
other => return Err(format!("Unknown mode: {other}")),
};
Ok(Box::new(EnterMode(mode)))