1 #[macro_use]
2 mod macros;
3 mod bash;
4 mod fish;
5 mod zsh;
6 mod powershell;
7 mod shell;
8
9 // Std
10 use std::io::Write;
11
12 // Internal
13 use app::parser::Parser;
14 use self::bash::BashGen;
15 use self::fish::FishGen;
16 use self::zsh::ZshGen;
17 use self::powershell::PowerShellGen;
18 pub use self::shell::Shell;
19
20 pub struct ComplGen<'a, 'b>
21 where
22 'a: 'b,
23 {
24 p: &'b Parser<'a, 'b>,
25 }
26
27 impl<'a, 'b> ComplGen<'a, 'b> {
new(p: &'b Parser<'a, 'b>) -> Self28 pub fn new(p: &'b Parser<'a, 'b>) -> Self { ComplGen { p: p } }
29
generate<W: Write>(&self, for_shell: Shell, buf: &mut W)30 pub fn generate<W: Write>(&self, for_shell: Shell, buf: &mut W) {
31 match for_shell {
32 Shell::Bash => BashGen::new(self.p).generate_to(buf),
33 Shell::Fish => FishGen::new(self.p).generate_to(buf),
34 Shell::Zsh => ZshGen::new(self.p).generate_to(buf),
35 Shell::PowerShell => PowerShellGen::new(self.p).generate_to(buf),
36 }
37 }
38 }
39
40 // Gets all subcommands including child subcommands in the form of 'name' where the name
41 // is a single word (i.e. "install") of the path to said subcommand (i.e.
42 // "rustup toolchain install")
43 //
44 // Also note, aliases are treated as their own subcommands but duplicates of whatever they're
45 // aliasing.
all_subcommand_names(p: &Parser) -> Vec<String>46 pub fn all_subcommand_names(p: &Parser) -> Vec<String> {
47 debugln!("all_subcommand_names;");
48 let mut subcmds: Vec<_> = subcommands_of(p)
49 .iter()
50 .map(|&(ref n, _)| n.clone())
51 .collect();
52 for sc_v in p.subcommands.iter().map(|s| all_subcommand_names(&s.p)) {
53 subcmds.extend(sc_v);
54 }
55 subcmds.sort();
56 subcmds.dedup();
57 subcmds
58 }
59
60 // Gets all subcommands including child subcommands in the form of ('name', 'bin_name') where the name
61 // is a single word (i.e. "install") of the path and full bin_name of said subcommand (i.e.
62 // "rustup toolchain install")
63 //
64 // Also note, aliases are treated as their own subcommands but duplicates of whatever they're
65 // aliasing.
all_subcommands(p: &Parser) -> Vec<(String, String)>66 pub fn all_subcommands(p: &Parser) -> Vec<(String, String)> {
67 debugln!("all_subcommands;");
68 let mut subcmds: Vec<_> = subcommands_of(p);
69 for sc_v in p.subcommands.iter().map(|s| all_subcommands(&s.p)) {
70 subcmds.extend(sc_v);
71 }
72 subcmds
73 }
74
75 // Gets all subcommands exlcuding child subcommands in the form of (name, bin_name) where the name
76 // is a single word (i.e. "install") and the bin_name is a space deliniated list of the path to said
77 // subcommand (i.e. "rustup toolchain install")
78 //
79 // Also note, aliases are treated as their own subcommands but duplicates of whatever they're
80 // aliasing.
subcommands_of(p: &Parser) -> Vec<(String, String)>81 pub fn subcommands_of(p: &Parser) -> Vec<(String, String)> {
82 debugln!(
83 "subcommands_of: name={}, bin_name={}",
84 p.meta.name,
85 p.meta.bin_name.as_ref().unwrap()
86 );
87 let mut subcmds = vec![];
88
89 debugln!(
90 "subcommands_of: Has subcommands...{:?}",
91 p.has_subcommands()
92 );
93 if !p.has_subcommands() {
94 let mut ret = vec![];
95 debugln!("subcommands_of: Looking for aliases...");
96 if let Some(ref aliases) = p.meta.aliases {
97 for &(n, _) in aliases {
98 debugln!("subcommands_of:iter:iter: Found alias...{}", n);
99 let mut als_bin_name: Vec<_> =
100 p.meta.bin_name.as_ref().unwrap().split(' ').collect();
101 als_bin_name.push(n);
102 let old = als_bin_name.len() - 2;
103 als_bin_name.swap_remove(old);
104 ret.push((n.to_owned(), als_bin_name.join(" ")));
105 }
106 }
107 return ret;
108 }
109 for sc in &p.subcommands {
110 debugln!(
111 "subcommands_of:iter: name={}, bin_name={}",
112 sc.p.meta.name,
113 sc.p.meta.bin_name.as_ref().unwrap()
114 );
115
116 debugln!("subcommands_of:iter: Looking for aliases...");
117 if let Some(ref aliases) = sc.p.meta.aliases {
118 for &(n, _) in aliases {
119 debugln!("subcommands_of:iter:iter: Found alias...{}", n);
120 let mut als_bin_name: Vec<_> =
121 p.meta.bin_name.as_ref().unwrap().split(' ').collect();
122 als_bin_name.push(n);
123 let old = als_bin_name.len() - 2;
124 als_bin_name.swap_remove(old);
125 subcmds.push((n.to_owned(), als_bin_name.join(" ")));
126 }
127 }
128 subcmds.push((
129 sc.p.meta.name.clone(),
130 sc.p.meta.bin_name.as_ref().unwrap().clone(),
131 ));
132 }
133 subcmds
134 }
135
get_all_subcommand_paths(p: &Parser, first: bool) -> Vec<String>136 pub fn get_all_subcommand_paths(p: &Parser, first: bool) -> Vec<String> {
137 debugln!("get_all_subcommand_paths;");
138 let mut subcmds = vec![];
139 if !p.has_subcommands() {
140 if !first {
141 let name = &*p.meta.name;
142 let path = p.meta.bin_name.as_ref().unwrap().clone().replace(" ", "__");
143 let mut ret = vec![path.clone()];
144 if let Some(ref aliases) = p.meta.aliases {
145 for &(n, _) in aliases {
146 ret.push(path.replace(name, n));
147 }
148 }
149 return ret;
150 }
151 return vec![];
152 }
153 for sc in &p.subcommands {
154 let name = &*sc.p.meta.name;
155 let path = sc.p
156 .meta
157 .bin_name
158 .as_ref()
159 .unwrap()
160 .clone()
161 .replace(" ", "__");
162 subcmds.push(path.clone());
163 if let Some(ref aliases) = sc.p.meta.aliases {
164 for &(n, _) in aliases {
165 subcmds.push(path.replace(name, n));
166 }
167 }
168 }
169 for sc_v in p.subcommands
170 .iter()
171 .map(|s| get_all_subcommand_paths(&s.p, false))
172 {
173 subcmds.extend(sc_v);
174 }
175 subcmds
176 }
177