aboutsummaryrefslogtreecommitdiff
path: root/clap/src/completions
diff options
context:
space:
mode:
Diffstat (limited to 'clap/src/completions')
-rw-r--r--clap/src/completions/bash.rs219
-rw-r--r--clap/src/completions/elvish.rs126
-rw-r--r--clap/src/completions/fish.rs99
-rw-r--r--clap/src/completions/macros.rs28
-rw-r--r--clap/src/completions/mod.rs179
-rw-r--r--clap/src/completions/powershell.rs139
-rw-r--r--clap/src/completions/shell.rs52
-rw-r--r--clap/src/completions/zsh.rs472
8 files changed, 0 insertions, 1314 deletions
diff --git a/clap/src/completions/bash.rs b/clap/src/completions/bash.rs
deleted file mode 100644
index 37dfa66..0000000
--- a/clap/src/completions/bash.rs
+++ /dev/null
@@ -1,219 +0,0 @@
-// Std
-use std::io::Write;
-
-// Internal
-use app::parser::Parser;
-use args::OptBuilder;
-use completions;
-
-pub struct BashGen<'a, 'b>
-where
- 'a: 'b,
-{
- p: &'b Parser<'a, 'b>,
-}
-
-impl<'a, 'b> BashGen<'a, 'b> {
- pub fn new(p: &'b Parser<'a, 'b>) -> Self { BashGen { p: p } }
-
- pub fn generate_to<W: Write>(&self, buf: &mut W) {
- w!(
- buf,
- format!(
- r#"_{name}() {{
- local i cur prev opts cmds
- COMPREPLY=()
- cur="${{COMP_WORDS[COMP_CWORD]}}"
- prev="${{COMP_WORDS[COMP_CWORD-1]}}"
- cmd=""
- opts=""
-
- for i in ${{COMP_WORDS[@]}}
- do
- case "${{i}}" in
- {name})
- cmd="{name}"
- ;;
- {subcmds}
- *)
- ;;
- esac
- done
-
- case "${{cmd}}" in
- {name})
- opts="{name_opts}"
- if [[ ${{cur}} == -* || ${{COMP_CWORD}} -eq 1 ]] ; then
- COMPREPLY=( $(compgen -W "${{opts}}" -- "${{cur}}") )
- return 0
- fi
- case "${{prev}}" in
- {name_opts_details}
- *)
- COMPREPLY=()
- ;;
- esac
- COMPREPLY=( $(compgen -W "${{opts}}" -- "${{cur}}") )
- return 0
- ;;
- {subcmd_details}
- esac
-}}
-
-complete -F _{name} -o bashdefault -o default {name}
-"#,
- name = self.p.meta.bin_name.as_ref().unwrap(),
- name_opts = self.all_options_for_path(self.p.meta.bin_name.as_ref().unwrap()),
- name_opts_details =
- self.option_details_for_path(self.p.meta.bin_name.as_ref().unwrap()),
- subcmds = self.all_subcommands(),
- subcmd_details = self.subcommand_details()
- ).as_bytes()
- );
- }
-
- fn all_subcommands(&self) -> String {
- debugln!("BashGen::all_subcommands;");
- let mut subcmds = String::new();
- let scs = completions::all_subcommand_names(self.p);
-
- for sc in &scs {
- subcmds = format!(
- r#"{}
- {name})
- cmd+="__{fn_name}"
- ;;"#,
- subcmds,
- name = sc,
- fn_name = sc.replace("-", "__")
- );
- }
-
- subcmds
- }
-
- fn subcommand_details(&self) -> String {
- debugln!("BashGen::subcommand_details;");
- let mut subcmd_dets = String::new();
- let mut scs = completions::get_all_subcommand_paths(self.p, true);
- scs.sort();
- scs.dedup();
-
- for sc in &scs {
- subcmd_dets = format!(
- r#"{}
- {subcmd})
- opts="{sc_opts}"
- if [[ ${{cur}} == -* || ${{COMP_CWORD}} -eq {level} ]] ; then
- COMPREPLY=( $(compgen -W "${{opts}}" -- "${{cur}}") )
- return 0
- fi
- case "${{prev}}" in
- {opts_details}
- *)
- COMPREPLY=()
- ;;
- esac
- COMPREPLY=( $(compgen -W "${{opts}}" -- "${{cur}}") )
- return 0
- ;;"#,
- subcmd_dets,
- subcmd = sc.replace("-", "__"),
- sc_opts = self.all_options_for_path(&*sc),
- level = sc.split("__").map(|_| 1).fold(0, |acc, n| acc + n),
- opts_details = self.option_details_for_path(&*sc)
- );
- }
-
- subcmd_dets
- }
-
- fn option_details_for_path(&self, path: &str) -> String {
- debugln!("BashGen::option_details_for_path: path={}", path);
- let mut p = self.p;
- for sc in path.split("__").skip(1) {
- debugln!("BashGen::option_details_for_path:iter: sc={}", sc);
- p = &find_subcmd!(p, sc).unwrap().p;
- }
- let mut opts = String::new();
- for o in p.opts() {
- if let Some(l) = o.s.long {
- opts = format!(
- "{}
- --{})
- COMPREPLY=({})
- return 0
- ;;",
- opts,
- l,
- self.vals_for(o)
- );
- }
- if let Some(s) = o.s.short {
- opts = format!(
- "{}
- -{})
- COMPREPLY=({})
- return 0
- ;;",
- opts,
- s,
- self.vals_for(o)
- );
- }
- }
- opts
- }
-
- fn vals_for(&self, o: &OptBuilder) -> String {
- debugln!("BashGen::vals_for: o={}", o.b.name);
- use args::AnyArg;
- if let Some(vals) = o.possible_vals() {
- format!(r#"$(compgen -W "{}" -- "${{cur}}")"#, vals.join(" "))
- } else {
- String::from(r#"$(compgen -f "${cur}")"#)
- }
- }
-
- fn all_options_for_path(&self, path: &str) -> String {
- debugln!("BashGen::all_options_for_path: path={}", path);
- let mut p = self.p;
- for sc in path.split("__").skip(1) {
- debugln!("BashGen::all_options_for_path:iter: sc={}", sc);
- p = &find_subcmd!(p, sc).unwrap().p;
- }
- let mut opts = shorts!(p).fold(String::new(), |acc, s| format!("{} -{}", acc, s));
- opts = format!(
- "{} {}",
- opts,
- longs!(p).fold(String::new(), |acc, l| format!("{} --{}", acc, l))
- );
- opts = format!(
- "{} {}",
- opts,
- p.positionals
- .values()
- .fold(String::new(), |acc, p| format!("{} {}", acc, p))
- );
- opts = format!(
- "{} {}",
- opts,
- p.subcommands
- .iter()
- .fold(String::new(), |acc, s| format!("{} {}", acc, s.p.meta.name))
- );
- for sc in &p.subcommands {
- if let Some(ref aliases) = sc.p.meta.aliases {
- opts = format!(
- "{} {}",
- opts,
- aliases
- .iter()
- .map(|&(n, _)| n)
- .fold(String::new(), |acc, a| format!("{} {}", acc, a))
- );
- }
- }
- opts
- }
-}
diff --git a/clap/src/completions/elvish.rs b/clap/src/completions/elvish.rs
deleted file mode 100644
index 9a5f21a..0000000
--- a/clap/src/completions/elvish.rs
+++ /dev/null
@@ -1,126 +0,0 @@
-// Std
-use std::io::Write;
-
-// Internal
-use app::parser::Parser;
-use INTERNAL_ERROR_MSG;
-
-pub struct ElvishGen<'a, 'b>
-where
- 'a: 'b,
-{
- p: &'b Parser<'a, 'b>,
-}
-
-impl<'a, 'b> ElvishGen<'a, 'b> {
- pub fn new(p: &'b Parser<'a, 'b>) -> Self { ElvishGen { p: p } }
-
- pub fn generate_to<W: Write>(&self, buf: &mut W) {
- let bin_name = self.p.meta.bin_name.as_ref().unwrap();
-
- let mut names = vec![];
- let subcommands_cases =
- generate_inner(self.p, "", &mut names);
-
- let result = format!(r#"
-edit:completion:arg-completer[{bin_name}] = [@words]{{
- fn spaces [n]{{
- repeat $n ' ' | joins ''
- }}
- fn cand [text desc]{{
- edit:complex-candidate $text &display-suffix=' '(spaces (- 14 (wcswidth $text)))$desc
- }}
- command = '{bin_name}'
- for word $words[1:-1] {{
- if (has-prefix $word '-') {{
- break
- }}
- command = $command';'$word
- }}
- completions = [{subcommands_cases}
- ]
- $completions[$command]
-}}
-"#,
- bin_name = bin_name,
- subcommands_cases = subcommands_cases
- );
-
- w!(buf, result.as_bytes());
- }
-}
-
-// Escape string inside single quotes
-fn escape_string(string: &str) -> String { string.replace("'", "''") }
-
-fn get_tooltip<T : ToString>(help: Option<&str>, data: T) -> String {
- match help {
- Some(help) => escape_string(help),
- _ => data.to_string()
- }
-}
-
-fn generate_inner<'a, 'b, 'p>(
- p: &'p Parser<'a, 'b>,
- previous_command_name: &str,
- names: &mut Vec<&'p str>,
-) -> String {
- debugln!("ElvishGen::generate_inner;");
- let command_name = if previous_command_name.is_empty() {
- p.meta.bin_name.as_ref().expect(INTERNAL_ERROR_MSG).clone()
- } else {
- format!("{};{}", previous_command_name, &p.meta.name)
- };
-
- let mut completions = String::new();
- let preamble = String::from("\n cand ");
-
- for option in p.opts() {
- if let Some(data) = option.s.short {
- let tooltip = get_tooltip(option.b.help, data);
- completions.push_str(&preamble);
- completions.push_str(format!("-{} '{}'", data, tooltip).as_str());
- }
- if let Some(data) = option.s.long {
- let tooltip = get_tooltip(option.b.help, data);
- completions.push_str(&preamble);
- completions.push_str(format!("--{} '{}'", data, tooltip).as_str());
- }
- }
-
- for flag in p.flags() {
- if let Some(data) = flag.s.short {
- let tooltip = get_tooltip(flag.b.help, data);
- completions.push_str(&preamble);
- completions.push_str(format!("-{} '{}'", data, tooltip).as_str());
- }
- if let Some(data) = flag.s.long {
- let tooltip = get_tooltip(flag.b.help, data);
- completions.push_str(&preamble);
- completions.push_str(format!("--{} '{}'", data, tooltip).as_str());
- }
- }
-
- for subcommand in &p.subcommands {
- let data = &subcommand.p.meta.name;
- let tooltip = get_tooltip(subcommand.p.meta.about, data);
- completions.push_str(&preamble);
- completions.push_str(format!("{} '{}'", data, tooltip).as_str());
- }
-
- let mut subcommands_cases = format!(
- r"
- &'{}'= {{{}
- }}",
- &command_name,
- completions
- );
-
- for subcommand in &p.subcommands {
- let subcommand_subcommands_cases =
- generate_inner(&subcommand.p, &command_name, names);
- subcommands_cases.push_str(&subcommand_subcommands_cases);
- }
-
- subcommands_cases
-}
diff --git a/clap/src/completions/fish.rs b/clap/src/completions/fish.rs
deleted file mode 100644
index c2c5a5e..0000000
--- a/clap/src/completions/fish.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-// Std
-use std::io::Write;
-
-// Internal
-use app::parser::Parser;
-
-pub struct FishGen<'a, 'b>
-where
- 'a: 'b,
-{
- p: &'b Parser<'a, 'b>,
-}
-
-impl<'a, 'b> FishGen<'a, 'b> {
- pub fn new(p: &'b Parser<'a, 'b>) -> Self { FishGen { p: p } }
-
- pub fn generate_to<W: Write>(&self, buf: &mut W) {
- let command = self.p.meta.bin_name.as_ref().unwrap();
- let mut buffer = String::new();
- gen_fish_inner(command, self, command, &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, comp_gen: &FishGen, subcommand: &str, buffer: &mut String) {
- debugln!("FishGen::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 {} -n ", root_command);
- if root_command == subcommand {
- basic_template.push_str("\"__fish_use_subcommand\"");
- } else {
- basic_template.push_str(format!("\"__fish_seen_subcommand_from {}\"", subcommand).as_str());
- }
-
- for option in comp_gen.p.opts() {
- let mut template = basic_template.clone();
- if let Some(data) = option.s.short {
- template.push_str(format!(" -s {}", data).as_str());
- }
- if let Some(data) = option.s.long {
- template.push_str(format!(" -l {}", data).as_str());
- }
- if let Some(data) = option.b.help {
- template.push_str(format!(" -d '{}'", escape_string(data)).as_str());
- }
- if let Some(ref data) = option.v.possible_vals {
- template.push_str(format!(" -r -f -a \"{}\"", data.join(" ")).as_str());
- }
- buffer.push_str(template.as_str());
- buffer.push_str("\n");
- }
-
- for flag in comp_gen.p.flags() {
- let mut template = basic_template.clone();
- if let Some(data) = flag.s.short {
- template.push_str(format!(" -s {}", data).as_str());
- }
- if let Some(data) = flag.s.long {
- template.push_str(format!(" -l {}", data).as_str());
- }
- if let Some(data) = flag.b.help {
- template.push_str(format!(" -d '{}'", escape_string(data)).as_str());
- }
- buffer.push_str(template.as_str());
- buffer.push_str("\n");
- }
-
- for subcommand in &comp_gen.p.subcommands {
- let mut template = basic_template.clone();
- template.push_str(" -f");
- template.push_str(format!(" -a \"{}\"", &subcommand.p.meta.name).as_str());
- if let Some(data) = subcommand.p.meta.about {
- template.push_str(format!(" -d '{}'", escape_string(data)).as_str())
- }
- buffer.push_str(template.as_str());
- buffer.push_str("\n");
- }
-
- // generate options of subcommands
- for subcommand in &comp_gen.p.subcommands {
- let sub_comp_gen = FishGen::new(&subcommand.p);
- gen_fish_inner(root_command, &sub_comp_gen, &subcommand.to_string(), buffer);
- }
-}
diff --git a/clap/src/completions/macros.rs b/clap/src/completions/macros.rs
deleted file mode 100644
index 653c72c..0000000
--- a/clap/src/completions/macros.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-macro_rules! w {
- ($buf:expr, $to_w:expr) => {
- match $buf.write_all($to_w) {
- Ok(..) => (),
- Err(..) => panic!("Failed to write to completions file"),
- }
- };
-}
-
-macro_rules! get_zsh_arg_conflicts {
- ($p:ident, $arg:ident, $msg:ident) => {
- if let Some(conf_vec) = $arg.blacklist() {
- let mut v = vec![];
- for arg_name in conf_vec {
- let arg = $p.find_any_arg(arg_name).expect($msg);
- if let Some(s) = arg.short() {
- v.push(format!("-{}", s));
- }
- if let Some(l) = arg.long() {
- v.push(format!("--{}", l));
- }
- }
- v.join(" ")
- } else {
- String::new()
- }
- }
-}
diff --git a/clap/src/completions/mod.rs b/clap/src/completions/mod.rs
deleted file mode 100644
index a3306d7..0000000
--- a/clap/src/completions/mod.rs
+++ /dev/null
@@ -1,179 +0,0 @@
-#[macro_use]
-mod macros;
-mod bash;
-mod fish;
-mod zsh;
-mod powershell;
-mod elvish;
-mod shell;
-
-// Std
-use std::io::Write;
-
-// Internal
-use app::parser::Parser;
-use self::bash::BashGen;
-use self::fish::FishGen;
-use self::zsh::ZshGen;
-use self::powershell::PowerShellGen;
-use self::elvish::ElvishGen;
-pub use self::shell::Shell;
-
-pub struct ComplGen<'a, 'b>
-where
- 'a: 'b,
-{
- p: &'b Parser<'a, 'b>,
-}
-
-impl<'a, 'b> ComplGen<'a, 'b> {
- pub fn new(p: &'b Parser<'a, 'b>) -> Self { ComplGen { p: p } }
-
- pub fn generate<W: Write>(&self, for_shell: Shell, buf: &mut W) {
- match for_shell {
- Shell::Bash => BashGen::new(self.p).generate_to(buf),
- Shell::Fish => FishGen::new(self.p).generate_to(buf),
- Shell::Zsh => ZshGen::new(self.p).generate_to(buf),
- Shell::PowerShell => PowerShellGen::new(self.p).generate_to(buf),
- Shell::Elvish => ElvishGen::new(self.p).generate_to(buf),
- }
- }
-}
-
-// Gets all subcommands including child subcommands in the form of 'name' where the name
-// is a single word (i.e. "install") of the path to said subcommand (i.e.
-// "rustup toolchain install")
-//
-// Also note, aliases are treated as their own subcommands but duplicates of whatever they're
-// aliasing.
-pub fn all_subcommand_names(p: &Parser) -> Vec<String> {
- debugln!("all_subcommand_names;");
- let mut subcmds: Vec<_> = subcommands_of(p)
- .iter()
- .map(|&(ref n, _)| n.clone())
- .collect();
- for sc_v in p.subcommands.iter().map(|s| all_subcommand_names(&s.p)) {
- subcmds.extend(sc_v);
- }
- subcmds.sort();
- subcmds.dedup();
- subcmds
-}
-
-// Gets all subcommands including child subcommands in the form of ('name', 'bin_name') where the name
-// is a single word (i.e. "install") of the path and full bin_name of said subcommand (i.e.
-// "rustup toolchain install")
-//
-// Also note, aliases are treated as their own subcommands but duplicates of whatever they're
-// aliasing.
-pub fn all_subcommands(p: &Parser) -> Vec<(String, String)> {
- debugln!("all_subcommands;");
- let mut subcmds: Vec<_> = subcommands_of(p);
- for sc_v in p.subcommands.iter().map(|s| all_subcommands(&s.p)) {
- subcmds.extend(sc_v);
- }
- subcmds
-}
-
-// Gets all subcommands excluding child subcommands in the form of (name, bin_name) where the name
-// is a single word (i.e. "install") and the bin_name is a space delineated list of the path to said
-// subcommand (i.e. "rustup toolchain install")
-//
-// Also note, aliases are treated as their own subcommands but duplicates of whatever they're
-// aliasing.
-pub fn subcommands_of(p: &Parser) -> Vec<(String, String)> {
- debugln!(
- "subcommands_of: name={}, bin_name={}",
- p.meta.name,
- p.meta.bin_name.as_ref().unwrap()
- );
- let mut subcmds = vec![];
-
- debugln!(
- "subcommands_of: Has subcommands...{:?}",
- p.has_subcommands()
- );
- if !p.has_subcommands() {
- let mut ret = vec![];
- debugln!("subcommands_of: Looking for aliases...");
- if let Some(ref aliases) = p.meta.aliases {
- for &(n, _) in aliases {
- debugln!("subcommands_of:iter:iter: Found alias...{}", n);
- let mut als_bin_name: Vec<_> =
- p.meta.bin_name.as_ref().unwrap().split(' ').collect();
- als_bin_name.push(n);
- let old = als_bin_name.len() - 2;
- als_bin_name.swap_remove(old);
- ret.push((n.to_owned(), als_bin_name.join(" ")));
- }
- }
- return ret;
- }
- for sc in &p.subcommands {
- debugln!(
- "subcommands_of:iter: name={}, bin_name={}",
- sc.p.meta.name,
- sc.p.meta.bin_name.as_ref().unwrap()
- );
-
- debugln!("subcommands_of:iter: Looking for aliases...");
- if let Some(ref aliases) = sc.p.meta.aliases {
- for &(n, _) in aliases {
- debugln!("subcommands_of:iter:iter: Found alias...{}", n);
- let mut als_bin_name: Vec<_> =
- p.meta.bin_name.as_ref().unwrap().split(' ').collect();
- als_bin_name.push(n);
- let old = als_bin_name.len() - 2;
- als_bin_name.swap_remove(old);
- subcmds.push((n.to_owned(), als_bin_name.join(" ")));
- }
- }
- subcmds.push((
- sc.p.meta.name.clone(),
- sc.p.meta.bin_name.as_ref().unwrap().clone(),
- ));
- }
- subcmds
-}
-
-pub fn get_all_subcommand_paths(p: &Parser, first: bool) -> Vec<String> {
- debugln!("get_all_subcommand_paths;");
- let mut subcmds = vec![];
- if !p.has_subcommands() {
- if !first {
- let name = &*p.meta.name;
- let path = p.meta.bin_name.as_ref().unwrap().clone().replace(" ", "__");
- let mut ret = vec![path.clone()];
- if let Some(ref aliases) = p.meta.aliases {
- for &(n, _) in aliases {
- ret.push(path.replace(name, n));
- }
- }
- return ret;
- }
- return vec![];
- }
- for sc in &p.subcommands {
- let name = &*sc.p.meta.name;
- let path = sc.p
- .meta
- .bin_name
- .as_ref()
- .unwrap()
- .clone()
- .replace(" ", "__");
- subcmds.push(path.clone());
- if let Some(ref aliases) = sc.p.meta.aliases {
- for &(n, _) in aliases {
- subcmds.push(path.replace(name, n));
- }
- }
- }
- for sc_v in p.subcommands
- .iter()
- .map(|s| get_all_subcommand_paths(&s.p, false))
- {
- subcmds.extend(sc_v);
- }
- subcmds
-}
diff --git a/clap/src/completions/powershell.rs b/clap/src/completions/powershell.rs
deleted file mode 100644
index 9fc77c7..0000000
--- a/clap/src/completions/powershell.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-// Std
-use std::io::Write;
-
-// Internal
-use app::parser::Parser;
-use INTERNAL_ERROR_MSG;
-
-pub struct PowerShellGen<'a, 'b>
-where
- 'a: 'b,
-{
- p: &'b Parser<'a, 'b>,
-}
-
-impl<'a, 'b> PowerShellGen<'a, 'b> {
- pub fn new(p: &'b Parser<'a, 'b>) -> Self { PowerShellGen { p: p } }
-
- pub fn generate_to<W: Write>(&self, buf: &mut W) {
- let bin_name = self.p.meta.bin_name.as_ref().unwrap();
-
- let mut names = vec![];
- let subcommands_cases =
- generate_inner(self.p, "", &mut names);
-
- let result = format!(r#"
-using namespace System.Management.Automation
-using namespace System.Management.Automation.Language
-
-Register-ArgumentCompleter -Native -CommandName '{bin_name}' -ScriptBlock {{
- param($wordToComplete, $commandAst, $cursorPosition)
-
- $commandElements = $commandAst.CommandElements
- $command = @(
- '{bin_name}'
- for ($i = 1; $i -lt $commandElements.Count; $i++) {{
- $element = $commandElements[$i]
- if ($element -isnot [StringConstantExpressionAst] -or
- $element.StringConstantType -ne [StringConstantType]::BareWord -or
- $element.Value.StartsWith('-')) {{
- break
- }}
- $element.Value
- }}) -join ';'
-
- $completions = @(switch ($command) {{{subcommands_cases}
- }})
-
- $completions.Where{{ $_.CompletionText -like "$wordToComplete*" }} |
- Sort-Object -Property ListItemText
-}}
-"#,
- bin_name = bin_name,
- subcommands_cases = subcommands_cases
- );
-
- w!(buf, result.as_bytes());
- }
-}
-
-// Escape string inside single quotes
-fn escape_string(string: &str) -> String { string.replace("'", "''") }
-
-fn get_tooltip<T : ToString>(help: Option<&str>, data: T) -> String {
- match help {
- Some(help) => escape_string(help),
- _ => data.to_string()
- }
-}
-
-fn generate_inner<'a, 'b, 'p>(
- p: &'p Parser<'a, 'b>,
- previous_command_name: &str,
- names: &mut Vec<&'p str>,
-) -> String {
- debugln!("PowerShellGen::generate_inner;");
- let command_name = if previous_command_name.is_empty() {
- p.meta.bin_name.as_ref().expect(INTERNAL_ERROR_MSG).clone()
- } else {
- format!("{};{}", previous_command_name, &p.meta.name)
- };
-
- let mut completions = String::new();
- let preamble = String::from("\n [CompletionResult]::new(");
-
- for option in p.opts() {
- if let Some(data) = option.s.short {
- let tooltip = get_tooltip(option.b.help, data);
- completions.push_str(&preamble);
- completions.push_str(format!("'-{}', '{}', {}, '{}')",
- data, data, "[CompletionResultType]::ParameterName", tooltip).as_str());
- }
- if let Some(data) = option.s.long {
- let tooltip = get_tooltip(option.b.help, data);
- completions.push_str(&preamble);
- completions.push_str(format!("'--{}', '{}', {}, '{}')",
- data, data, "[CompletionResultType]::ParameterName", tooltip).as_str());
- }
- }
-
- for flag in p.flags() {
- if let Some(data) = flag.s.short {
- let tooltip = get_tooltip(flag.b.help, data);
- completions.push_str(&preamble);
- completions.push_str(format!("'-{}', '{}', {}, '{}')",
- data, data, "[CompletionResultType]::ParameterName", tooltip).as_str());
- }
- if let Some(data) = flag.s.long {
- let tooltip = get_tooltip(flag.b.help, data);
- completions.push_str(&preamble);
- completions.push_str(format!("'--{}', '{}', {}, '{}')",
- data, data, "[CompletionResultType]::ParameterName", tooltip).as_str());
- }
- }
-
- for subcommand in &p.subcommands {
- let data = &subcommand.p.meta.name;
- let tooltip = get_tooltip(subcommand.p.meta.about, data);
- completions.push_str(&preamble);
- completions.push_str(format!("'{}', '{}', {}, '{}')",
- data, data, "[CompletionResultType]::ParameterValue", tooltip).as_str());
- }
-
- let mut subcommands_cases = format!(
- r"
- '{}' {{{}
- break
- }}",
- &command_name,
- completions
- );
-
- for subcommand in &p.subcommands {
- let subcommand_subcommands_cases =
- generate_inner(&subcommand.p, &command_name, names);
- subcommands_cases.push_str(&subcommand_subcommands_cases);
- }
-
- subcommands_cases
-}
diff --git a/clap/src/completions/shell.rs b/clap/src/completions/shell.rs
deleted file mode 100644
index 19aab86..0000000
--- a/clap/src/completions/shell.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-#[allow(deprecated, unused_imports)]
-use std::ascii::AsciiExt;
-use std::str::FromStr;
-use std::fmt;
-
-/// Describes which shell to produce a completions file for
-#[cfg_attr(feature = "lints", allow(enum_variant_names))]
-#[derive(Debug, Copy, Clone)]
-pub enum Shell {
- /// Generates a .bash completion file for the Bourne Again SHell (BASH)
- Bash,
- /// Generates a .fish completion file for the Friendly Interactive SHell (fish)
- Fish,
- /// Generates a completion file for the Z SHell (ZSH)
- Zsh,
- /// Generates a completion file for PowerShell
- PowerShell,
- /// Generates a completion file for Elvish
- Elvish,
-}
-
-impl Shell {
- /// A list of possible variants in `&'static str` form
- pub fn variants() -> [&'static str; 5] { ["zsh", "bash", "fish", "powershell", "elvish"] }
-}
-
-impl FromStr for Shell {
- type Err = String;
-
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- match s {
- "ZSH" | _ if s.eq_ignore_ascii_case("zsh") => Ok(Shell::Zsh),
- "FISH" | _ if s.eq_ignore_ascii_case("fish") => Ok(Shell::Fish),
- "BASH" | _ if s.eq_ignore_ascii_case("bash") => Ok(Shell::Bash),
- "POWERSHELL" | _ if s.eq_ignore_ascii_case("powershell") => Ok(Shell::PowerShell),
- "ELVISH" | _ if s.eq_ignore_ascii_case("elvish") => Ok(Shell::Elvish),
- _ => Err(String::from("[valid values: bash, fish, zsh, powershell, elvish]")),
- }
- }
-}
-
-impl fmt::Display for Shell {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- Shell::Bash => write!(f, "BASH"),
- Shell::Fish => write!(f, "FISH"),
- Shell::Zsh => write!(f, "ZSH"),
- Shell::PowerShell => write!(f, "POWERSHELL"),
- Shell::Elvish => write!(f, "ELVISH"),
- }
- }
-}
diff --git a/clap/src/completions/zsh.rs b/clap/src/completions/zsh.rs
deleted file mode 100644
index 5d23fd2..0000000
--- a/clap/src/completions/zsh.rs
+++ /dev/null
@@ -1,472 +0,0 @@
-// Std
-use std::io::Write;
-#[allow(deprecated, unused_imports)]
-use std::ascii::AsciiExt;
-
-// Internal
-use app::App;
-use app::parser::Parser;
-use args::{AnyArg, ArgSettings};
-use completions;
-use INTERNAL_ERROR_MSG;
-
-pub struct ZshGen<'a, 'b>
-where
- 'a: 'b,
-{
- p: &'b Parser<'a, 'b>,
-}
-
-impl<'a, 'b> ZshGen<'a, 'b> {
- pub fn new(p: &'b Parser<'a, 'b>) -> Self {
- debugln!("ZshGen::new;");
- ZshGen { p: p }
- }
-
- pub fn generate_to<W: Write>(&self, buf: &mut W) {
- debugln!("ZshGen::generate_to;");
- w!(
- buf,
- format!(
- "\
-#compdef {name}
-
-autoload -U is-at-least
-
-_{name}() {{
- typeset -A opt_args
- typeset -a _arguments_options
- local ret=1
-
- if is-at-least 5.2; then
- _arguments_options=(-s -S -C)
- else
- _arguments_options=(-s -C)
- fi
-
- local context curcontext=\"$curcontext\" state line
- {initial_args}
- {subcommands}
-}}
-
-{subcommand_details}
-
-_{name} \"$@\"",
- name = self.p.meta.bin_name.as_ref().unwrap(),
- initial_args = get_args_of(self.p),
- subcommands = get_subcommands_of(self.p),
- subcommand_details = subcommand_details(self.p)
- ).as_bytes()
- );
- }
-}
-
-// Displays the commands of a subcommand
-// (( $+functions[_[bin_name_underscore]_commands] )) ||
-// _[bin_name_underscore]_commands() {
-// local commands; commands=(
-// '[arg_name]:[arg_help]'
-// )
-// _describe -t commands '[bin_name] commands' commands "$@"
-//
-// Where the following variables are present:
-// [bin_name_underscore]: The full space delineated bin_name, where spaces have been replaced by
-// underscore characters
-// [arg_name]: The name of the subcommand
-// [arg_help]: The help message of the subcommand
-// [bin_name]: The full space delineated bin_name
-//
-// Here's a snippet from rustup:
-//
-// (( $+functions[_rustup_commands] )) ||
-// _rustup_commands() {
-// local commands; commands=(
-// 'show:Show the active and installed toolchains'
-// 'update:Update Rust toolchains'
-// # ... snip for brevity
-// 'help:Prints this message or the help of the given subcommand(s)'
-// )
-// _describe -t commands 'rustup commands' commands "$@"
-//
-fn subcommand_details(p: &Parser) -> String {
- debugln!("ZshGen::subcommand_details;");
- // First we do ourself
- let mut ret = vec![
- format!(
- "\
-(( $+functions[_{bin_name_underscore}_commands] )) ||
-_{bin_name_underscore}_commands() {{
- local commands; commands=(
- {subcommands_and_args}
- )
- _describe -t commands '{bin_name} commands' commands \"$@\"
-}}",
- bin_name_underscore = p.meta.bin_name.as_ref().unwrap().replace(" ", "__"),
- bin_name = p.meta.bin_name.as_ref().unwrap(),
- subcommands_and_args = subcommands_of(p)
- ),
- ];
-
- // Next we start looping through all the children, grandchildren, etc.
- let mut all_subcommands = completions::all_subcommands(p);
- all_subcommands.sort();
- all_subcommands.dedup();
- for &(_, ref bin_name) in &all_subcommands {
- debugln!("ZshGen::subcommand_details:iter: bin_name={}", bin_name);
- ret.push(format!(
- "\
-(( $+functions[_{bin_name_underscore}_commands] )) ||
-_{bin_name_underscore}_commands() {{
- local commands; commands=(
- {subcommands_and_args}
- )
- _describe -t commands '{bin_name} commands' commands \"$@\"
-}}",
- bin_name_underscore = bin_name.replace(" ", "__"),
- bin_name = bin_name,
- subcommands_and_args = subcommands_of(parser_of(p, bin_name))
- ));
- }
-
- ret.join("\n")
-}
-
-// Generates subcommand completions in form of
-//
-// '[arg_name]:[arg_help]'
-//
-// Where:
-// [arg_name]: the subcommand's name
-// [arg_help]: the help message of the subcommand
-//
-// A snippet from rustup:
-// 'show:Show the active and installed toolchains'
-// 'update:Update Rust toolchains'
-fn subcommands_of(p: &Parser) -> String {
- debugln!("ZshGen::subcommands_of;");
- let mut ret = vec![];
- fn add_sc(sc: &App, n: &str, ret: &mut Vec<String>) {
- debugln!("ZshGen::add_sc;");
- let s = format!(
- "\"{name}:{help}\" \\",
- name = n,
- help = sc.p
- .meta
- .about
- .unwrap_or("")
- .replace("[", "\\[")
- .replace("]", "\\]")
- );
- if !s.is_empty() {
- ret.push(s);
- }
- }
-
- // The subcommands
- for sc in p.subcommands() {
- debugln!(
- "ZshGen::subcommands_of:iter: subcommand={}",
- sc.p.meta.name
- );
- add_sc(sc, &sc.p.meta.name, &mut ret);
- if let Some(ref v) = sc.p.meta.aliases {
- for alias in v.iter().filter(|&&(_, vis)| vis).map(|&(n, _)| n) {
- add_sc(sc, alias, &mut ret);
- }
- }
- }
-
- ret.join("\n")
-}
-
-// Get's the subcommand section of a completion file
-// This looks roughly like:
-//
-// case $state in
-// ([bin_name]_args)
-// curcontext=\"${curcontext%:*:*}:[name_hyphen]-command-$words[1]:\"
-// case $line[1] in
-//
-// ([name])
-// _arguments -C -s -S \
-// [subcommand_args]
-// && ret=0
-//
-// [RECURSIVE_CALLS]
-//
-// ;;",
-//
-// [repeat]
-//
-// esac
-// ;;
-// esac",
-//
-// Where the following variables are present:
-// [name] = The subcommand name in the form of "install" for "rustup toolchain install"
-// [bin_name] = The full space delineated bin_name such as "rustup toolchain install"
-// [name_hyphen] = The full space delineated bin_name, but replace spaces with hyphens
-// [repeat] = From the same recursive calls, but for all subcommands
-// [subcommand_args] = The same as zsh::get_args_of
-fn get_subcommands_of(p: &Parser) -> String {
- debugln!("get_subcommands_of;");
-
- debugln!(
- "get_subcommands_of: Has subcommands...{:?}",
- p.has_subcommands()
- );
- if !p.has_subcommands() {
- return String::new();
- }
-
- let sc_names = completions::subcommands_of(p);
-
- let mut subcmds = vec![];
- for &(ref name, ref bin_name) in &sc_names {
- let mut v = vec![format!("({})", name)];
- let subcommand_args = get_args_of(parser_of(p, &*bin_name));
- if !subcommand_args.is_empty() {
- v.push(subcommand_args);
- }
- let subcommands = get_subcommands_of(parser_of(p, &*bin_name));
- if !subcommands.is_empty() {
- v.push(subcommands);
- }
- v.push(String::from(";;"));
- subcmds.push(v.join("\n"));
- }
-
- format!(
- "case $state in
- ({name})
- words=($line[{pos}] \"${{words[@]}}\")
- (( CURRENT += 1 ))
- curcontext=\"${{curcontext%:*:*}}:{name_hyphen}-command-$line[{pos}]:\"
- case $line[{pos}] in
- {subcommands}
- esac
- ;;
-esac",
- name = p.meta.name,
- name_hyphen = p.meta.bin_name.as_ref().unwrap().replace(" ", "-"),
- subcommands = subcmds.join("\n"),
- pos = p.positionals().len() + 1
- )
-}
-
-fn parser_of<'a, 'b>(p: &'b Parser<'a, 'b>, sc: &str) -> &'b Parser<'a, 'b> {
- debugln!("parser_of: sc={}", sc);
- if sc == p.meta.bin_name.as_ref().unwrap_or(&String::new()) {
- return p;
- }
- &p.find_subcommand(sc).expect(INTERNAL_ERROR_MSG).p
-}
-
-// Writes out the args section, which ends up being the flags, opts and postionals, and a jump to
-// another ZSH function if there are subcommands.
-// The structer works like this:
-// ([conflicting_args]) [multiple] arg [takes_value] [[help]] [: :(possible_values)]
-// ^-- list '-v -h' ^--'*' ^--'+' ^-- list 'one two three'
-//
-// An example from the rustup command:
-//
-// _arguments -C -s -S \
-// '(-h --help --verbose)-v[Enable verbose output]' \
-// '(-V -v --version --verbose --help)-h[Prints help information]' \
-// # ... snip for brevity
-// ':: :_rustup_commands' \ # <-- displays subcommands
-// '*::: :->rustup' \ # <-- displays subcommand args and child subcommands
-// && ret=0
-//
-// The args used for _arguments are as follows:
-// -C: modify the $context internal variable
-// -s: Allow stacking of short args (i.e. -a -b -c => -abc)
-// -S: Do not complete anything after '--' and treat those as argument values
-fn get_args_of(p: &Parser) -> String {
- debugln!("get_args_of;");
- let mut ret = vec![String::from("_arguments \"${_arguments_options[@]}\" \\")];
- let opts = write_opts_of(p);
- let flags = write_flags_of(p);
- let positionals = write_positionals_of(p);
- let sc_or_a = if p.has_subcommands() {
- format!(
- "\":: :_{name}_commands\" \\",
- name = p.meta.bin_name.as_ref().unwrap().replace(" ", "__")
- )
- } else {
- String::new()
- };
- let sc = if p.has_subcommands() {
- format!("\"*::: :->{name}\" \\", name = p.meta.name)
- } else {
- String::new()
- };
-
- if !opts.is_empty() {
- ret.push(opts);
- }
- if !flags.is_empty() {
- ret.push(flags);
- }
- if !positionals.is_empty() {
- ret.push(positionals);
- }
- if !sc_or_a.is_empty() {
- ret.push(sc_or_a);
- }
- if !sc.is_empty() {
- ret.push(sc);
- }
- ret.push(String::from("&& ret=0"));
-
- ret.join("\n")
-}
-
-// Escape help string inside single quotes and brackets
-fn escape_help(string: &str) -> String {
- string
- .replace("\\", "\\\\")
- .replace("'", "'\\''")
- .replace("[", "\\[")
- .replace("]", "\\]")
-}
-
-// Escape value string inside single quotes and parentheses
-fn escape_value(string: &str) -> String {
- string
- .replace("\\", "\\\\")
- .replace("'", "'\\''")
- .replace("(", "\\(")
- .replace(")", "\\)")
- .replace(" ", "\\ ")
-}
-
-fn write_opts_of(p: &Parser) -> String {
- debugln!("write_opts_of;");
- let mut ret = vec![];
- for o in p.opts() {
- debugln!("write_opts_of:iter: o={}", o.name());
- let help = o.help().map_or(String::new(), escape_help);
- let mut conflicts = get_zsh_arg_conflicts!(p, o, INTERNAL_ERROR_MSG);
- conflicts = if conflicts.is_empty() {
- String::new()
- } else {
- format!("({})", conflicts)
- };
-
- let multiple = if o.is_set(ArgSettings::Multiple) {
- "*"
- } else {
- ""
- };
- let pv = if let Some(pv_vec) = o.possible_vals() {
- format!(": :({})", pv_vec.iter().map(
- |v| escape_value(*v)).collect::<Vec<String>>().join(" "))
- } else {
- String::new()
- };
- if let Some(short) = o.short() {
- let s = format!(
- "'{conflicts}{multiple}-{arg}+[{help}]{possible_values}' \\",
- conflicts = conflicts,
- multiple = multiple,
- arg = short,
- possible_values = pv,
- help = help
- );
-
- debugln!("write_opts_of:iter: Wrote...{}", &*s);
- ret.push(s);
- }
- if let Some(long) = o.long() {
- let l = format!(
- "'{conflicts}{multiple}--{arg}=[{help}]{possible_values}' \\",
- conflicts = conflicts,
- multiple = multiple,
- arg = long,
- possible_values = pv,
- help = help
- );
-
- debugln!("write_opts_of:iter: Wrote...{}", &*l);
- ret.push(l);
- }
- }
-
- ret.join("\n")
-}
-
-fn write_flags_of(p: &Parser) -> String {
- debugln!("write_flags_of;");
- let mut ret = vec![];
- for f in p.flags() {
- debugln!("write_flags_of:iter: f={}", f.name());
- let help = f.help().map_or(String::new(), escape_help);
- let mut conflicts = get_zsh_arg_conflicts!(p, f, INTERNAL_ERROR_MSG);
- conflicts = if conflicts.is_empty() {
- String::new()
- } else {
- format!("({})", conflicts)
- };
-
- let multiple = if f.is_set(ArgSettings::Multiple) {
- "*"
- } else {
- ""
- };
- if let Some(short) = f.short() {
- let s = format!(
- "'{conflicts}{multiple}-{arg}[{help}]' \\",
- multiple = multiple,
- conflicts = conflicts,
- arg = short,
- help = help
- );
-
- debugln!("write_flags_of:iter: Wrote...{}", &*s);
- ret.push(s);
- }
-
- if let Some(long) = f.long() {
- let l = format!(
- "'{conflicts}{multiple}--{arg}[{help}]' \\",
- conflicts = conflicts,
- multiple = multiple,
- arg = long,
- help = help
- );
-
- debugln!("write_flags_of:iter: Wrote...{}", &*l);
- ret.push(l);
- }
- }
-
- ret.join("\n")
-}
-
-fn write_positionals_of(p: &Parser) -> String {
- debugln!("write_positionals_of;");
- let mut ret = vec![];
- for arg in p.positionals() {
- debugln!("write_positionals_of:iter: arg={}", arg.b.name);
- let a = format!(
- "'{optional}:{name}{help}:{action}' \\",
- optional = if !arg.b.is_set(ArgSettings::Required) { ":" } else { "" },
- name = arg.b.name,
- help = arg.b
- .help
- .map_or("".to_owned(), |v| " -- ".to_owned() + v)
- .replace("[", "\\[")
- .replace("]", "\\]"),
- action = arg.possible_vals().map_or("_files".to_owned(), |values| {
- format!("({})",
- values.iter().map(|v| escape_value(*v)).collect::<Vec<String>>().join(" "))
- })
- );
-
- debugln!("write_positionals_of:iter: Wrote...{}", a);
- ret.push(a);
- }
-
- ret.join("\n")
-}