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:
@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user