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