1 use 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]
29 pub 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 
70 impl FromStr for ValueHint {
71     type Err = String;
from_str(s: &str) -> Result<Self, <Self as FromStr>::Err>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