From c44cd946a888c1bc5376e2b14b05ce31d642a11f Mon Sep 17 00:00:00 2001 From: Colin Nelson Date: Thu, 5 Mar 2026 22:57:53 +0000 Subject: [PATCH] argh_complete: fix subcommand completion for zsh --- argh/examples/completion_example.rs | 42 +++++++++++++++++++++++++++++ argh_complete/Cargo.toml | 2 +- argh_complete/src/zsh.rs | 6 ++--- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/argh/examples/completion_example.rs b/argh/examples/completion_example.rs index 3d67961..9bdc476 100644 --- a/argh/examples/completion_example.rs +++ b/argh/examples/completion_example.rs @@ -17,6 +17,7 @@ struct MyCmd { enum Subcommands { Completion(CompletionCmd), DoThings(DoThingsCmd), + DoMoreThings(DoMoreThingsCmd), } #[derive(FromArgs, ArgsInfo)] @@ -41,6 +42,39 @@ struct DoThingsCmd { quick: bool, } +#[derive(FromArgs, ArgsInfo)] +#[argh(subcommand)] +enum MoreThingsSubcommands { + ThingOne(ThingOneCommand), + ThingTwo(ThingTwoCommand), +} + +#[derive(FromArgs, ArgsInfo)] +/// Do thing one. +#[argh(subcommand, name = "one")] +struct ThingOneCommand { + /// do it slowly + #[argh(switch, short = 's')] + slow: bool, +} + +#[derive(FromArgs, ArgsInfo)] +/// Do thing two. +#[argh(subcommand, name = "two")] +struct ThingTwoCommand { + /// do it quickly + #[argh(switch, short = 'q')] + quick: bool, +} + +#[derive(FromArgs, ArgsInfo)] +/// Do some more things. +#[argh(subcommand, name = "do-more-things")] +struct DoMoreThingsCmd { + #[argh(subcommand)] + cmd: MoreThingsSubcommands, +} + fn main() { let args: MyCmd = argh::from_env(); @@ -74,5 +108,13 @@ fn main() { Subcommands::DoThings(cmd) => { println!("Doing {} things (quick: {})", cmd.count, cmd.quick); } + Subcommands::DoMoreThings(cmd) => match cmd.cmd { + MoreThingsSubcommands::ThingOne(cmd) => { + println!("Doing more thing one (slow: {})", cmd.slow); + } + MoreThingsSubcommands::ThingTwo(cmd) => { + println!("Doing more thing two (quick: {})", cmd.quick); + } + }, } } diff --git a/argh_complete/Cargo.toml b/argh_complete/Cargo.toml index 24c21be..9322eb3 100644 --- a/argh_complete/Cargo.toml +++ b/argh_complete/Cargo.toml @@ -9,4 +9,4 @@ description = "Autocompletion generators for argh-based CLIs" readme = "README.md" [dependencies] -argh_shared = { version = "0.1.13", path = "../argh_shared" } +argh_shared.workspace = true diff --git a/argh_complete/src/zsh.rs b/argh_complete/src/zsh.rs index d12958b..744cf42 100644 --- a/argh_complete/src/zsh.rs +++ b/argh_complete/src/zsh.rs @@ -78,7 +78,7 @@ fn generate_zsh_args(out: &mut String, prefix: &str, cmd: &CommandInfoWithArgs<' if has_short && has_long { let short = format!("-{}", flag.short.unwrap()); def.push_str(&format!( - "'({} {})'{{{},{}}}[{}]", + "'({} {})'{{{},{}}}'[{}]'", short, flag.long, short, flag.long, desc )); } else if has_long { @@ -107,9 +107,9 @@ fn generate_zsh_args(out: &mut String, prefix: &str, cmd: &CommandInfoWithArgs<' writeln!(out, "{} '{}:{}'", ind, subcmd.name, desc).unwrap(); } writeln!(out, "{} )", ind).unwrap(); - writeln!(out, "{} _describe -t commands '{} commands' subcommands", ind, cmd.name) - .unwrap(); writeln!(out, "{} if (( CURRENT == 1 )); then", ind).unwrap(); + writeln!(out, "{} _describe -t commands '{} commands' subcommands", ind, cmd.name) + .unwrap(); writeln!(out, "{} return", ind).unwrap(); writeln!(out, "{} fi", ind).unwrap(); writeln!(out, "{} local cmd=$words[1]", ind).unwrap();