feat(command): implement command aliasing

Implement command aliasing in CmdRegistry and update command parsing to
resolve aliases.

- Added `aliases` field to `CmdRegistry` .
- Added `alias()` method to register short names.
- Added `resolve()` method to map aliases to canonical names.
- Updated `parse()` and `interactive()` to use `resolve()` .
- Added unit tests for alias resolution in `src/command/parse.rs` .

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
This commit is contained in:
Edward Langley
2026-04-08 22:27:36 -07:00
parent fb85e98abe
commit 1813d2a662
2 changed files with 77 additions and 0 deletions

View File

@ -113,15 +113,32 @@ struct CmdEntry {
#[derive(Default)]
pub struct CmdRegistry {
entries: Vec<CmdEntry>,
aliases: Vec<(&'static str, &'static str)>,
}
impl CmdRegistry {
pub fn new() -> Self {
Self {
entries: Vec::new(),
aliases: Vec::new(),
}
}
/// Register a short name that resolves to a canonical command name.
pub fn alias(&mut self, short: &'static str, canonical: &'static str) {
self.aliases.push((short, canonical));
}
/// Resolve a command name through the alias table.
fn resolve<'a>(&'a self, name: &'a str) -> &'a str {
for (alias, canonical) in &self.aliases {
if *alias == name {
return canonical;
}
}
name
}
/// Register a command with both a text parser and an interactive constructor.
/// The name is derived from a prototype command instance.
pub fn register(&mut self, prototype: &dyn Cmd, parse: ParseFn, interactive: InteractiveFn) {
@ -162,6 +179,7 @@ impl CmdRegistry {
/// Construct a command from text arguments (script/headless).
pub fn parse(&self, name: &str, args: &[String]) -> Result<Box<dyn Cmd>, String> {
let name = self.resolve(name);
for e in &self.entries {
if e.name == name {
return (e.parse)(args);
@ -179,6 +197,7 @@ impl CmdRegistry {
args: &[String],
ctx: &CmdContext,
) -> Result<Box<dyn Cmd>, String> {
let name = self.resolve(name);
for e in &self.entries {
if e.name == name {
return (e.interactive)(args, ctx);
@ -2781,6 +2800,12 @@ pub fn default_registry() -> CmdRegistry {
// ── Wizard ───────────────────────────────────────────────────────────
r.register_nullary(|| Box::new(HandleWizardKey));
// ── Aliases (short names for common commands) ────────────────────────
r.alias("add-cat", "add-category");
r.alias("formula", "add-formula");
r.alias("add-view", "create-view");
r.alias("q!", "force-quit");
r
}