clap/completions/
mod.rs
1#[macro_use]
2mod macros;
3mod bash;
4mod elvish;
5mod fish;
6mod powershell;
7mod shell;
8mod zsh;
9
10use std::io::Write;
12
13pub use crate::completions::shell::Shell;
15use crate::{
16 app::parser::Parser,
17 completions::{
18 bash::BashGen, elvish::ElvishGen, fish::FishGen, powershell::PowerShellGen, zsh::ZshGen,
19 },
20};
21
22pub struct ComplGen<'a, 'b>
23where
24 'a: 'b,
25{
26 p: &'b Parser<'a, 'b>,
27}
28
29impl<'a, 'b> ComplGen<'a, 'b> {
30 pub fn new(p: &'b Parser<'a, 'b>) -> Self {
31 ComplGen { p }
32 }
33
34 pub fn generate<W: Write>(&self, for_shell: Shell, buf: &mut W) {
35 match for_shell {
36 Shell::Bash => BashGen::new(self.p).generate_to(buf),
37 Shell::Fish => FishGen::new(self.p).generate_to(buf),
38 Shell::Zsh => ZshGen::new(self.p).generate_to(buf),
39 Shell::PowerShell => PowerShellGen::new(self.p).generate_to(buf),
40 Shell::Elvish => ElvishGen::new(self.p).generate_to(buf),
41 }
42 }
43}
44
45pub fn all_subcommand_names(p: &Parser) -> Vec<String> {
52 debugln!("all_subcommand_names;");
53 let mut subcmds: Vec<_> = subcommands_of(p)
54 .iter()
55 .map(|&(ref n, _)| n.clone())
56 .collect();
57 for sc_v in p.subcommands.iter().map(|s| all_subcommand_names(&s.p)) {
58 subcmds.extend(sc_v);
59 }
60 subcmds.sort();
61 subcmds.dedup();
62 subcmds
63}
64
65pub fn all_subcommands(p: &Parser) -> Vec<(String, String)> {
72 debugln!("all_subcommands;");
73 let mut subcmds: Vec<_> = subcommands_of(p);
74 for sc_v in p.subcommands.iter().map(|s| all_subcommands(&s.p)) {
75 subcmds.extend(sc_v);
76 }
77 subcmds
78}
79
80pub fn subcommands_of(p: &Parser) -> Vec<(String, String)> {
87 debugln!(
88 "subcommands_of: name={}, bin_name={}",
89 p.meta.name,
90 p.meta.bin_name.as_ref().unwrap()
91 );
92 let mut subcmds = vec![];
93
94 debugln!(
95 "subcommands_of: Has subcommands...{:?}",
96 p.has_subcommands()
97 );
98 if !p.has_subcommands() {
99 let mut ret = vec![];
100 debugln!("subcommands_of: Looking for aliases...");
101 if let Some(ref aliases) = p.meta.aliases {
102 for &(n, _) in aliases {
103 debugln!("subcommands_of:iter:iter: Found alias...{}", n);
104 let mut als_bin_name: Vec<_> =
105 p.meta.bin_name.as_ref().unwrap().split(' ').collect();
106 als_bin_name.push(n);
107 let old = als_bin_name.len() - 2;
108 als_bin_name.swap_remove(old);
109 ret.push((n.to_owned(), als_bin_name.join(" ")));
110 }
111 }
112 return ret;
113 }
114 for sc in &p.subcommands {
115 debugln!(
116 "subcommands_of:iter: name={}, bin_name={}",
117 sc.p.meta.name,
118 sc.p.meta.bin_name.as_ref().unwrap()
119 );
120
121 debugln!("subcommands_of:iter: Looking for aliases...");
122 if let Some(ref aliases) = sc.p.meta.aliases {
123 for &(n, _) in aliases {
124 debugln!("subcommands_of:iter:iter: Found alias...{}", n);
125 let mut als_bin_name: Vec<_> =
126 p.meta.bin_name.as_ref().unwrap().split(' ').collect();
127 als_bin_name.push(n);
128 let old = als_bin_name.len() - 2;
129 als_bin_name.swap_remove(old);
130 subcmds.push((n.to_owned(), als_bin_name.join(" ")));
131 }
132 }
133 subcmds.push((
134 sc.p.meta.name.clone(),
135 sc.p.meta.bin_name.as_ref().unwrap().clone(),
136 ));
137 }
138 subcmds
139}
140
141pub fn get_all_subcommand_paths(p: &Parser, first: bool) -> Vec<String> {
142 debugln!("get_all_subcommand_paths;");
143 let mut subcmds = vec![];
144 if !p.has_subcommands() {
145 if !first {
146 let name = &*p.meta.name;
147 let path = p.meta.bin_name.as_ref().unwrap().clone().replace(" ", "__");
148 let mut ret = vec![path.clone()];
149 if let Some(ref aliases) = p.meta.aliases {
150 for &(n, _) in aliases {
151 ret.push(path.replace(name, n));
152 }
153 }
154 return ret;
155 }
156 return vec![];
157 }
158 for sc in &p.subcommands {
159 let name = &*sc.p.meta.name;
160 let path =
161 sc.p.meta
162 .bin_name
163 .as_ref()
164 .unwrap()
165 .clone()
166 .replace(" ", "__");
167 subcmds.push(path.clone());
168 if let Some(ref aliases) = sc.p.meta.aliases {
169 for &(n, _) in aliases {
170 subcmds.push(path.replace(name, n));
171 }
172 }
173 }
174 for sc_v in p
175 .subcommands
176 .iter()
177 .map(|s| get_all_subcommand_paths(&s.p, false))
178 {
179 subcmds.extend(sc_v);
180 }
181 subcmds
182}