garden/cmds/
completion.rs1use std::io::Write;
2
3use anyhow::Result;
4use clap::{crate_version, value_parser, Arg, Command, CommandFactory, Parser};
5
6use crate::{cli, model};
7
8#[derive(Parser, Clone, Debug)]
10#[command(author, about, long_about)]
11pub struct CompletionOptions {
12 #[arg(long, short)]
14 commands: bool,
15 #[arg(default_value_t = clap_complete::Shell::Bash, value_parser = value_parser!(clap_complete::Shell))]
17 pub shell: clap_complete::Shell,
18}
19
20pub fn main(options: &cli::MainOptions, completion_options: &CompletionOptions) -> Result<()> {
22 let mut cmd = cli::MainOptions::command();
23
24 if completion_options.commands {
26 let app_context = model::ApplicationContext::from_options(options)?;
27 let config = app_context.get_root_config();
28 for name in config.commands.keys() {
29 cmd = cmd.subcommand(
30 Command::new(name)
31 .about(format!("Custom {name} command"))
32 .arg(
33 Arg::new("keep_going")
34 .help("Continue to the next tree when errors occur")
35 .short('k')
36 .long("keep-going"),
37 )
38 .arg(
39 Arg::new("no-errexit")
40 .help("Do not pass -e to the shell")
41 .short('n')
42 .long("no-errexit"),
43 )
44 .arg(
45 Arg::new("no-wordsplit")
46 .help("Do not pass -o shwordsplit to zsh")
47 .short('z')
48 .long("no-wordsplit"),
49 )
50 .arg(
51 Arg::new("queries")
52 .help("Tree queries to find trees where commands will be run"),
53 )
54 .arg(
55 Arg::new("arguments")
56 .help("Arguments to forward to custom commands")
57 .last(true),
58 ),
59 );
60 }
61 }
62
63 let comment = format!("\n# Generated by garden v{}.\n", crate_version!());
64 let mut buf = Vec::with_capacity(16384);
67 clap_complete::generate(completion_options.shell, &mut cmd, "garden", &mut buf);
68 buf.extend_from_slice(comment.as_bytes());
69 std::io::stdout().write_all(&buf).unwrap_or(());
70
71 Ok(())
72}