Skip to content

Commit d87dee6

Browse files
authored
Merge pull request #5476 from pzmarzly/issue-4265
feat(complete): generate completions for visible aliases
2 parents f087c39 + 5000d58 commit d87dee6

File tree

15 files changed

+461
-292
lines changed

15 files changed

+461
-292
lines changed

clap_builder/src/builder/command.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3441,6 +3441,13 @@ impl Command {
34413441
&self.name
34423442
}
34433443

3444+
/// Get all known names of the cmd (i.e. primary name and visible aliases).
3445+
pub fn get_name_and_visible_aliases(&self) -> Vec<&str> {
3446+
let mut names = vec![self.name.as_str()];
3447+
names.extend(self.get_visible_aliases());
3448+
names
3449+
}
3450+
34443451
/// Get the version of the cmd.
34453452
#[inline]
34463453
pub fn get_version(&self) -> Option<&str> {

clap_complete/src/generator/utils.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,15 @@ pub fn subcommands(p: &Command) -> Vec<(String, String)> {
4747
sc.get_name(),
4848
sc_bin_name
4949
);
50-
5150
subcmds.push((sc.get_name().to_string(), sc_bin_name.to_string()));
51+
52+
for alias in sc.get_visible_aliases() {
53+
debug!(
54+
"subcommands:iter: alias={}, bin_name={}",
55+
alias, sc_bin_name
56+
);
57+
subcmds.push((alias.to_string(), sc_bin_name.to_string()));
58+
}
5259
}
5360

5461
subcmds

clap_complete/src/shells/elvish.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,13 @@ fn escape_help<T: ToString>(help: Option<&StyledStr>, data: T) -> String {
6767
fn generate_inner(p: &Command, previous_command_name: &str) -> String {
6868
debug!("generate_inner");
6969

70-
let command_name = if previous_command_name.is_empty() {
71-
p.get_bin_name().expect(INTERNAL_ERROR_MSG).to_string()
70+
let command_names = if previous_command_name.is_empty() {
71+
vec![p.get_bin_name().expect(INTERNAL_ERROR_MSG).to_string()]
7272
} else {
73-
format!("{};{}", previous_command_name, &p.get_name())
73+
p.get_name_and_visible_aliases()
74+
.into_iter()
75+
.map(|name| format!("{};{}", previous_command_name, name))
76+
.collect()
7477
};
7578

7679
let mut completions = String::new();
@@ -113,23 +116,29 @@ fn generate_inner(p: &Command, previous_command_name: &str) -> String {
113116
}
114117

115118
for subcommand in p.get_subcommands() {
116-
let data = &subcommand.get_name();
117-
let tooltip = escape_help(subcommand.get_about(), data);
119+
for name in subcommand.get_name_and_visible_aliases() {
120+
let tooltip = escape_help(subcommand.get_about(), name);
118121

119-
completions.push_str(&preamble);
120-
completions.push_str(format!("{data} '{tooltip}'").as_str());
122+
completions.push_str(&preamble);
123+
completions.push_str(format!("{name} '{tooltip}'").as_str());
124+
}
121125
}
122126

123-
let mut subcommands_cases = format!(
124-
r"
127+
let mut subcommands_cases = String::new();
128+
for command_name in &command_names {
129+
subcommands_cases.push_str(&format!(
130+
r"
125131
&'{}'= {{{}
126132
}}",
127-
&command_name, completions
128-
);
133+
&command_name, completions
134+
));
135+
}
129136

130137
for subcommand in p.get_subcommands() {
131-
let subcommand_subcommands_cases = generate_inner(subcommand, &command_name);
132-
subcommands_cases.push_str(&subcommand_subcommands_cases);
138+
for command_name in &command_names {
139+
let subcommand_subcommands_cases = generate_inner(subcommand, command_name);
140+
subcommands_cases.push_str(&subcommand_subcommands_cases);
141+
}
133142
}
134143

135144
subcommands_cases

clap_complete/src/shells/fish.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ fn gen_fish_inner(
7575
.map(|command| format!("__fish_seen_subcommand_from {command}"))
7676
.chain(
7777
cmd.get_subcommands()
78-
.map(|command| format!("not __fish_seen_subcommand_from {command}"))
78+
.flat_map(Command::get_name_and_visible_aliases)
79+
.map(|name| format!("not __fish_seen_subcommand_from {name}"))
7980
)
8081
.collect::<Vec<_>>()
8182
.join("; and ")
@@ -135,24 +136,28 @@ fn gen_fish_inner(
135136
}
136137

137138
for subcommand in cmd.get_subcommands() {
138-
let mut template = basic_template.clone();
139+
for subcommand_name in subcommand.get_name_and_visible_aliases() {
140+
let mut template = basic_template.clone();
139141

140-
template.push_str(" -f");
141-
template.push_str(format!(" -a \"{}\"", &subcommand.get_name()).as_str());
142+
template.push_str(" -f");
143+
template.push_str(format!(" -a \"{}\"", subcommand_name).as_str());
142144

143-
if let Some(data) = subcommand.get_about() {
144-
template.push_str(format!(" -d '{}'", escape_help(data)).as_str());
145-
}
145+
if let Some(data) = subcommand.get_about() {
146+
template.push_str(format!(" -d '{}'", escape_help(data)).as_str());
147+
}
146148

147-
buffer.push_str(template.as_str());
148-
buffer.push('\n');
149+
buffer.push_str(template.as_str());
150+
buffer.push('\n');
151+
}
149152
}
150153

151154
// generate options of subcommands
152155
for subcommand in cmd.get_subcommands() {
153-
let mut parent_commands: Vec<_> = parent_commands.into();
154-
parent_commands.push(subcommand.get_name());
155-
gen_fish_inner(root_command, &parent_commands, subcommand, buffer);
156+
for subcommand_name in subcommand.get_name_and_visible_aliases() {
157+
let mut parent_commands: Vec<_> = parent_commands.into();
158+
parent_commands.push(subcommand_name);
159+
gen_fish_inner(root_command, &parent_commands, subcommand, buffer);
160+
}
156161
}
157162
}
158163

clap_complete/src/shells/powershell.rs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,13 @@ fn escape_help<T: ToString>(help: Option<&StyledStr>, data: T) -> String {
7272
fn generate_inner(p: &Command, previous_command_name: &str) -> String {
7373
debug!("generate_inner");
7474

75-
let command_name = if previous_command_name.is_empty() {
76-
p.get_bin_name().expect(INTERNAL_ERROR_MSG).to_string()
75+
let command_names = if previous_command_name.is_empty() {
76+
vec![p.get_bin_name().expect(INTERNAL_ERROR_MSG).to_string()]
7777
} else {
78-
format!("{};{}", previous_command_name, &p.get_name())
78+
p.get_name_and_visible_aliases()
79+
.into_iter()
80+
.map(|name| format!("{};{}", previous_command_name, name))
81+
.collect()
7982
};
8083

8184
let mut completions = String::new();
@@ -90,27 +93,31 @@ fn generate_inner(p: &Command, previous_command_name: &str) -> String {
9093
}
9194

9295
for subcommand in p.get_subcommands() {
93-
let data = &subcommand.get_name();
94-
let tooltip = escape_help(subcommand.get_about(), data);
95-
96-
completions.push_str(&preamble);
97-
completions.push_str(
98-
format!("'{data}', '{data}', [CompletionResultType]::ParameterValue, '{tooltip}')")
99-
.as_str(),
100-
);
96+
for name in subcommand.get_name_and_visible_aliases() {
97+
let tooltip = escape_help(subcommand.get_about(), name);
98+
completions.push_str(&preamble);
99+
completions.push_str(&format!(
100+
"'{name}', '{name}', [CompletionResultType]::ParameterValue, '{tooltip}')"
101+
));
102+
}
101103
}
102104

103-
let mut subcommands_cases = format!(
104-
r"
105+
let mut subcommands_cases = String::new();
106+
for command_name in &command_names {
107+
subcommands_cases.push_str(&format!(
108+
r"
105109
'{}' {{{}
106110
break
107111
}}",
108-
&command_name, completions
109-
);
112+
command_name, completions
113+
));
114+
}
110115

111116
for subcommand in p.get_subcommands() {
112-
let subcommand_subcommands_cases = generate_inner(subcommand, &command_name);
113-
subcommands_cases.push_str(&subcommand_subcommands_cases);
117+
for command_name in &command_names {
118+
let subcommand_subcommands_cases = generate_inner(subcommand, command_name);
119+
subcommands_cases.push_str(&subcommand_subcommands_cases);
120+
}
114121
}
115122

116123
subcommands_cases

clap_complete/src/shells/zsh.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,15 @@ _{bin_name_underscore}_commands() {{
110110
ret.push(parent_text);
111111

112112
// Next we start looping through all the children, grandchildren, etc.
113-
let mut all_subcommands = utils::all_subcommands(p);
113+
let mut all_subcommand_bins: Vec<_> = utils::all_subcommands(p)
114+
.into_iter()
115+
.map(|(_sc_name, bin_name)| bin_name)
116+
.collect();
114117

115-
all_subcommands.sort();
116-
all_subcommands.dedup();
118+
all_subcommand_bins.sort();
119+
all_subcommand_bins.dedup();
117120

118-
for (_, ref bin_name) in &all_subcommands {
121+
for bin_name in &all_subcommand_bins {
119122
debug!("subcommand_details:iter: bin_name={bin_name}");
120123

121124
ret.push(format!(

0 commit comments

Comments
 (0)