1use std::str::FromStr;
2
3/// Provide shell with hint on how to complete an argument.
4///
5/// See [Arg::value_hint][crate::Arg::value_hint] to set this on an argument.
6///
7/// See the `clap_complete` crate for completion script generation.
8///
9/// Overview of which hints are supported by which shell:
10///
11/// | Hint | zsh | fish[^1]|
12/// | ---------------------- | --- | ------- |
13/// | `AnyPath` | Yes | Yes |
14/// | `FilePath` | Yes | Yes |
15/// | `DirPath` | Yes | Yes |
16/// | `ExecutablePath` | Yes | Partial |
17/// | `CommandName` | Yes | Yes |
18/// | `CommandString` | Yes | Partial |
19/// | `CommandWithArguments` | Yes | |
20/// | `Username` | Yes | Yes |
21/// | `Hostname` | Yes | Yes |
22/// | `Url` | Yes | |
23/// | `EmailAddress` | Yes | |
24///
25/// [^1]: fish completions currently only support named arguments (e.g. -o or --opt), not
26/// positional arguments.
27#[derive(Debug, Default, PartialEq, Eq, Hash, Copy, Clone)]
28#[non_exhaustive]
29pub enum ValueHint {
30 /// Default value if hint is not specified. Follows shell default behavior, which is usually
31 /// auto-completing filenames.
32 #[default]
33 Unknown,
34 /// None of the hints below apply. Disables shell completion for this argument.
35 Other,
36 /// Any existing path.
37 AnyPath,
38 /// Path to a file.
39 FilePath,
40 /// Path to a directory.
41 DirPath,
42 /// Path to an executable file.
43 ExecutablePath,
44 /// Name of a command, without arguments. May be relative to PATH, or full path to executable.
45 CommandName,
46 /// A single string containing a command and its arguments.
47 CommandString,
48 /// Capture the remaining arguments as a command name and arguments for that command. This is
49 /// common when writing shell wrappers that execute anther command, for example `sudo` or `env`.
50 ///
51 /// This hint is special, the argument must be a positional argument and have
52 /// [`.num_args(1..)`] and Command must use [`Command::trailing_var_arg(true)`]. The result is that the
53 /// command line `my_app ls -la /` will be parsed as `["ls", "-la", "/"]` and clap won't try to
54 /// parse the `-la` argument itself.
55 ///
56 /// [`Command::trailing_var_arg(true)`]: crate::Command::trailing_var_arg
57 /// [`.num_args(1..)`]: crate::Arg::num_args()
58 CommandWithArguments,
59 /// Name of a local operating system user.
60 Username,
61 /// Host name of a computer.
62 /// Shells usually parse `/etc/hosts` and `.ssh/known_hosts` to complete hostnames.
63 Hostname,
64 /// Complete web address.
65 Url,
66 /// Email address.
67 EmailAddress,
68}
69
70impl FromStr for ValueHint {
71 type Err = String;
72 fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
73 Ok(match &*s.to_ascii_lowercase() {
74 "unknown" => ValueHint::Unknown,
75 "other" => ValueHint::Other,
76 "anypath" => ValueHint::AnyPath,
77 "filepath" => ValueHint::FilePath,
78 "dirpath" => ValueHint::DirPath,
79 "executablepath" => ValueHint::ExecutablePath,
80 "commandname" => ValueHint::CommandName,
81 "commandstring" => ValueHint::CommandString,
82 "commandwitharguments" => ValueHint::CommandWithArguments,
83 "username" => ValueHint::Username,
84 "hostname" => ValueHint::Hostname,
85 "url" => ValueHint::Url,
86 "emailaddress" => ValueHint::EmailAddress,
87 _ => return Err(format!("unknown ValueHint: `{s}`")),
88 })
89 }
90}
91