1 //! How to use value hints and generate shell completions.
2 //!
3 //! Usage with zsh:
4 //! ```sh
5 //! cargo run --example value_hints_derive -- --generate=zsh > /usr/local/share/zsh/site-functions/_value_hints_derive
6 //! compinit
7 //! ./target/debug/examples/value_hints_derive --<TAB>
8 //! ```
9 //! fish:
10 //! ```sh
11 //! cargo run --example value_hints_derive -- --generate=fish > value_hints_derive.fish
12 //! . ./value_hints_derive.fish
13 //! ./target/debug/examples/value_hints_derive --<TAB>
14 //! ```
15 use clap::{Args, Command, CommandFactory, Parser, Subcommand, ValueHint};
16 use clap_complete::{generate, Generator, Shell};
17 use std::ffi::OsString;
18 use std::io;
19 use std::path::PathBuf;
20
21 #[derive(Parser, Debug, PartialEq)]
22 #[command(name = "completion-derive")]
23 struct Opt {
24 // If provided, outputs the completion file for given shell
25 #[arg(long = "generate", value_enum)]
26 generator: Option<Shell>,
27 #[command(subcommand)]
28 command: Option<Commands>,
29 }
30
31 #[derive(Subcommand, Debug, PartialEq)]
32 enum Commands {
33 #[command(visible_alias = "hint")]
34 ValueHint(ValueHintOpt),
35 }
36
37 #[derive(Args, Debug, PartialEq)]
38 struct ValueHintOpt {
39 // Showcasing all possible ValueHints:
40 #[arg(long, value_hint = ValueHint::Unknown)]
41 unknown: Option<String>,
42 #[arg(long, value_hint = ValueHint::Other)]
43 other: Option<String>,
44 #[arg(short, long, value_hint = ValueHint::AnyPath)]
45 path: Option<PathBuf>,
46 #[arg(short, long, value_hint = ValueHint::FilePath)]
47 file: Option<PathBuf>,
48 #[arg(short, long, value_hint = ValueHint::DirPath)]
49 dir: Option<PathBuf>,
50 #[arg(short, long, value_hint = ValueHint::ExecutablePath)]
51 exe: Option<PathBuf>,
52 #[arg(long, value_hint = ValueHint::CommandName)]
53 cmd_name: Option<OsString>,
54 #[arg(short, long, value_hint = ValueHint::CommandString)]
55 cmd: Option<String>,
56 // Command::trailing_var_ar is required to use ValueHint::CommandWithArguments
57 #[arg(trailing_var_arg = true, value_hint = ValueHint::CommandWithArguments)]
58 command_with_args: Vec<String>,
59 #[arg(short, long, value_hint = ValueHint::Username)]
60 user: Option<String>,
61 #[arg(long, value_hint = ValueHint::Hostname)]
62 host: Option<String>,
63 #[arg(long, value_hint = ValueHint::Url)]
64 url: Option<String>,
65 #[arg(long, value_hint = ValueHint::EmailAddress)]
66 email: Option<String>,
67 }
68
print_completions<G: Generator>(gen: G, cmd: &mut Command)69 fn print_completions<G: Generator>(gen: G, cmd: &mut Command) {
70 generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout());
71 }
72
main()73 fn main() {
74 let opt = Opt::parse();
75
76 if let Some(generator) = opt.generator {
77 let mut cmd = Opt::command();
78 eprintln!("Generating completion file for {generator:?}...");
79 print_completions(generator, &mut cmd);
80 } else {
81 println!("{opt:#?}");
82 }
83 }
84