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//! ``` 15use clap::{Args, Command, CommandFactory, Parser, Subcommand, ValueHint}; 16use clap_complete::{generate, Generator, Shell}; 17use std::ffi::OsString; 18use std::io; 19use std::path::PathBuf; 20 21#[derive(Parser, Debug, PartialEq)] 22#[command(name = "completion-derive")] 23struct 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)] 32enum Commands { 33 #[command(visible_alias = "hint")] 34 ValueHint(ValueHintOpt), 35} 36 37#[derive(Args, Debug, PartialEq)] 38struct 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 69fn print_completions<G: Generator>(gen: G, cmd: &mut Command) { 70 generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout()); 71} 72 73fn 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