summaryrefslogtreecommitdiffstats
path: root/vendor/clap_complete/src/shells/fish.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/clap_complete/src/shells/fish.rs
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/clap_complete/src/shells/fish.rs')
-rw-r--r--vendor/clap_complete/src/shells/fish.rs192
1 files changed, 192 insertions, 0 deletions
diff --git a/vendor/clap_complete/src/shells/fish.rs b/vendor/clap_complete/src/shells/fish.rs
new file mode 100644
index 000000000..9b516084b
--- /dev/null
+++ b/vendor/clap_complete/src/shells/fish.rs
@@ -0,0 +1,192 @@
+use std::io::Write;
+
+use clap::*;
+
+use crate::generator::{utils, Generator};
+
+/// Generate fish completion file
+///
+/// Note: The fish generator currently only supports named options (-o/--option), not positional arguments.
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub struct Fish;
+
+impl Generator for Fish {
+ fn file_name(&self, name: &str) -> String {
+ format!("{}.fish", name)
+ }
+
+ fn generate(&self, cmd: &Command, buf: &mut dyn Write) {
+ let bin_name = cmd
+ .get_bin_name()
+ .expect("crate::generate should have set the bin_name");
+
+ let mut buffer = String::new();
+ gen_fish_inner(bin_name, &[], cmd, &mut buffer);
+ w!(buf, buffer.as_bytes());
+ }
+}
+
+// Escape string inside single quotes
+fn escape_string(string: &str) -> String {
+ string.replace('\\', "\\\\").replace('\'', "\\'")
+}
+
+fn gen_fish_inner(
+ root_command: &str,
+ parent_commands: &[&str],
+ cmd: &Command,
+ buffer: &mut String,
+) {
+ debug!("gen_fish_inner");
+ // example :
+ //
+ // complete
+ // -c {command}
+ // -d "{description}"
+ // -s {short}
+ // -l {long}
+ // -a "{possible_arguments}"
+ // -r # if require parameter
+ // -f # don't use file completion
+ // -n "__fish_use_subcommand" # complete for command "myprog"
+ // -n "__fish_seen_subcommand_from subcmd1" # complete for command "myprog subcmd1"
+
+ let mut basic_template = format!("complete -c {}", root_command);
+
+ if parent_commands.is_empty() {
+ if cmd.has_subcommands() {
+ basic_template.push_str(" -n \"__fish_use_subcommand\"");
+ }
+ } else {
+ basic_template.push_str(
+ format!(
+ " -n \"{}\"",
+ parent_commands
+ .iter()
+ .map(|command| format!("__fish_seen_subcommand_from {}", command))
+ .chain(
+ cmd.get_subcommands()
+ .map(|command| format!("not __fish_seen_subcommand_from {}", command))
+ )
+ .collect::<Vec<_>>()
+ .join("; and ")
+ )
+ .as_str(),
+ );
+ }
+
+ debug!("gen_fish_inner: parent_commands={:?}", parent_commands);
+
+ for option in cmd.get_opts() {
+ let mut template = basic_template.clone();
+
+ if let Some(shorts) = option.get_short_and_visible_aliases() {
+ for short in shorts {
+ template.push_str(format!(" -s {}", short).as_str());
+ }
+ }
+
+ if let Some(longs) = option.get_long_and_visible_aliases() {
+ for long in longs {
+ template.push_str(format!(" -l {}", escape_string(long)).as_str());
+ }
+ }
+
+ if let Some(data) = option.get_help() {
+ template.push_str(format!(" -d '{}'", escape_string(data)).as_str());
+ }
+
+ template.push_str(value_completion(option).as_str());
+
+ buffer.push_str(template.as_str());
+ buffer.push('\n');
+ }
+
+ for flag in utils::flags(cmd) {
+ let mut template = basic_template.clone();
+
+ if let Some(shorts) = flag.get_short_and_visible_aliases() {
+ for short in shorts {
+ template.push_str(format!(" -s {}", short).as_str());
+ }
+ }
+
+ if let Some(longs) = flag.get_long_and_visible_aliases() {
+ for long in longs {
+ template.push_str(format!(" -l {}", escape_string(long)).as_str());
+ }
+ }
+
+ if let Some(data) = flag.get_help() {
+ template.push_str(format!(" -d '{}'", escape_string(data)).as_str());
+ }
+
+ buffer.push_str(template.as_str());
+ buffer.push('\n');
+ }
+
+ for subcommand in cmd.get_subcommands() {
+ let mut template = basic_template.clone();
+
+ template.push_str(" -f");
+ template.push_str(format!(" -a \"{}\"", &subcommand.get_name()).as_str());
+
+ if let Some(data) = subcommand.get_about() {
+ template.push_str(format!(" -d '{}'", escape_string(data)).as_str())
+ }
+
+ buffer.push_str(template.as_str());
+ buffer.push('\n');
+ }
+
+ // generate options of subcommands
+ for subcommand in cmd.get_subcommands() {
+ let mut parent_commands: Vec<_> = parent_commands.into();
+ parent_commands.push(subcommand.get_name());
+ gen_fish_inner(root_command, &parent_commands, subcommand, buffer);
+ }
+}
+
+fn value_completion(option: &Arg) -> String {
+ if !option.is_takes_value_set() {
+ return "".to_string();
+ }
+
+ if let Some(data) = option.get_possible_values() {
+ // We return the possible values with their own empty description e.g. {a\t,b\t}
+ // this makes sure that a and b don't get the description of the option or argument
+ format!(
+ " -r -f -a \"{{{}}}\"",
+ data.iter()
+ .filter_map(|value| if value.is_hide_set() {
+ None
+ } else {
+ Some(format!(
+ "{}\t{}",
+ escape_string(value.get_name()).as_str(),
+ escape_string(value.get_help().unwrap_or_default()).as_str()
+ ))
+ })
+ .collect::<Vec<_>>()
+ .join(",")
+ )
+ } else {
+ // NB! If you change this, please also update the table in `ValueHint` documentation.
+ match option.get_value_hint() {
+ ValueHint::Unknown => " -r",
+ // fish has no built-in support to distinguish these
+ ValueHint::AnyPath | ValueHint::FilePath | ValueHint::ExecutablePath => " -r -F",
+ ValueHint::DirPath => " -r -f -a \"(__fish_complete_directories)\"",
+ // It seems fish has no built-in support for completing command + arguments as
+ // single string (CommandString). Complete just the command name.
+ ValueHint::CommandString | ValueHint::CommandName => {
+ " -r -f -a \"(__fish_complete_command)\""
+ }
+ ValueHint::Username => " -r -f -a \"(__fish_complete_users)\"",
+ ValueHint::Hostname => " -r -f -a \"(__fish_print_hostnames)\"",
+ // Disable completion for others
+ _ => " -r -f",
+ }
+ .to_string()
+ }
+}