Skip to content

Commit 5b3d45f

Browse files
committed
refactor(complete): Extract function for options
To be used in a following commit.
1 parent 8ea75fa commit 5b3d45f

File tree

1 file changed

+99
-87
lines changed

1 file changed

+99
-87
lines changed

clap_complete/src/engine/complete.rs

Lines changed: 99 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -157,93 +157,7 @@ fn complete_arg(
157157
{
158158
completions.extend(complete_arg_value(arg.to_value(), positional, current_dir));
159159
}
160-
161-
if arg.is_empty() {
162-
completions.extend(longs_and_visible_aliases(cmd));
163-
completions.extend(hidden_longs_aliases(cmd));
164-
165-
let dash_or_arg = if arg.is_empty() {
166-
"-".into()
167-
} else {
168-
arg.to_value_os().to_string_lossy()
169-
};
170-
completions.extend(
171-
shorts_and_visible_aliases(cmd)
172-
.into_iter()
173-
.map(|comp| comp.add_prefix(dash_or_arg.to_string())),
174-
);
175-
} else if arg.is_stdio() {
176-
// HACK: Assuming knowledge of is_stdio
177-
let dash_or_arg = if arg.is_empty() {
178-
"-".into()
179-
} else {
180-
arg.to_value_os().to_string_lossy()
181-
};
182-
completions.extend(
183-
shorts_and_visible_aliases(cmd)
184-
.into_iter()
185-
.map(|comp| comp.add_prefix(dash_or_arg.to_string())),
186-
);
187-
188-
completions.extend(longs_and_visible_aliases(cmd));
189-
completions.extend(hidden_longs_aliases(cmd));
190-
} else if arg.is_escape() {
191-
// HACK: Assuming knowledge of is_escape
192-
completions.extend(longs_and_visible_aliases(cmd));
193-
completions.extend(hidden_longs_aliases(cmd));
194-
} else if let Some((flag, value)) = arg.to_long() {
195-
if let Ok(flag) = flag {
196-
if let Some(value) = value {
197-
if let Some(arg) = cmd.get_arguments().find(|a| a.get_long() == Some(flag))
198-
{
199-
completions.extend(
200-
complete_arg_value(value.to_str().ok_or(value), arg, current_dir)
201-
.into_iter()
202-
.map(|comp| comp.add_prefix(format!("--{flag}="))),
203-
);
204-
}
205-
} else {
206-
completions.extend(longs_and_visible_aliases(cmd).into_iter().filter(
207-
|comp| comp.get_value().starts_with(format!("--{flag}").as_str()),
208-
));
209-
completions.extend(hidden_longs_aliases(cmd).into_iter().filter(|comp| {
210-
comp.get_value().starts_with(format!("--{flag}").as_str())
211-
}));
212-
}
213-
}
214-
} else if let Some(short) = arg.to_short() {
215-
if !short.is_negative_number() {
216-
// Find the first takes_values option.
217-
let (leading_flags, takes_value_opt, mut short) = parse_shortflags(cmd, short);
218-
219-
// Clone `short` to `peek_short` to peek whether the next flag is a `=`.
220-
if let Some(opt) = takes_value_opt {
221-
let mut peek_short = short.clone();
222-
let has_equal = if let Some(Ok('=')) = peek_short.next_flag() {
223-
short.next_flag();
224-
true
225-
} else {
226-
false
227-
};
228-
229-
let value = short.next_value_os().unwrap_or(OsStr::new(""));
230-
completions.extend(
231-
complete_arg_value(value.to_str().ok_or(value), opt, current_dir)
232-
.into_iter()
233-
.map(|comp| {
234-
let sep = if has_equal { "=" } else { "" };
235-
comp.add_prefix(format!("-{leading_flags}{sep}"))
236-
}),
237-
);
238-
} else {
239-
completions.extend(
240-
shorts_and_visible_aliases(cmd)
241-
.into_iter()
242-
.map(|comp| comp.add_prefix(format!("-{leading_flags}"))),
243-
);
244-
}
245-
}
246-
}
160+
completions.extend(complete_option(arg, cmd, current_dir));
247161
}
248162
ParseState::Pos(..) => {
249163
if let Some(positional) = cmd
@@ -297,6 +211,104 @@ fn complete_arg(
297211
Ok(completions)
298212
}
299213

214+
fn complete_option(
215+
arg: &clap_lex::ParsedArg<'_>,
216+
cmd: &clap::Command,
217+
current_dir: Option<&std::path::Path>,
218+
) -> Vec<CompletionCandidate> {
219+
let mut completions = Vec::<CompletionCandidate>::new();
220+
if arg.is_empty() {
221+
completions.extend(longs_and_visible_aliases(cmd));
222+
completions.extend(hidden_longs_aliases(cmd));
223+
224+
let dash_or_arg = if arg.is_empty() {
225+
"-".into()
226+
} else {
227+
arg.to_value_os().to_string_lossy()
228+
};
229+
completions.extend(
230+
shorts_and_visible_aliases(cmd)
231+
.into_iter()
232+
.map(|comp| comp.add_prefix(dash_or_arg.to_string())),
233+
);
234+
} else if arg.is_stdio() {
235+
// HACK: Assuming knowledge of is_stdio
236+
let dash_or_arg = if arg.is_empty() {
237+
"-".into()
238+
} else {
239+
arg.to_value_os().to_string_lossy()
240+
};
241+
completions.extend(
242+
shorts_and_visible_aliases(cmd)
243+
.into_iter()
244+
.map(|comp| comp.add_prefix(dash_or_arg.to_string())),
245+
);
246+
247+
completions.extend(longs_and_visible_aliases(cmd));
248+
completions.extend(hidden_longs_aliases(cmd));
249+
} else if arg.is_escape() {
250+
// HACK: Assuming knowledge of is_escape
251+
completions.extend(longs_and_visible_aliases(cmd));
252+
completions.extend(hidden_longs_aliases(cmd));
253+
} else if let Some((flag, value)) = arg.to_long() {
254+
if let Ok(flag) = flag {
255+
if let Some(value) = value {
256+
if let Some(arg) = cmd.get_arguments().find(|a| a.get_long() == Some(flag)) {
257+
completions.extend(
258+
complete_arg_value(value.to_str().ok_or(value), arg, current_dir)
259+
.into_iter()
260+
.map(|comp| comp.add_prefix(format!("--{flag}="))),
261+
);
262+
}
263+
} else {
264+
completions.extend(
265+
longs_and_visible_aliases(cmd)
266+
.into_iter()
267+
.filter(|comp| comp.get_value().starts_with(format!("--{flag}").as_str())),
268+
);
269+
completions.extend(
270+
hidden_longs_aliases(cmd)
271+
.into_iter()
272+
.filter(|comp| comp.get_value().starts_with(format!("--{flag}").as_str())),
273+
);
274+
}
275+
}
276+
} else if let Some(short) = arg.to_short() {
277+
if !short.is_negative_number() {
278+
// Find the first takes_values option.
279+
let (leading_flags, takes_value_opt, mut short) = parse_shortflags(cmd, short);
280+
281+
// Clone `short` to `peek_short` to peek whether the next flag is a `=`.
282+
if let Some(opt) = takes_value_opt {
283+
let mut peek_short = short.clone();
284+
let has_equal = if let Some(Ok('=')) = peek_short.next_flag() {
285+
short.next_flag();
286+
true
287+
} else {
288+
false
289+
};
290+
291+
let value = short.next_value_os().unwrap_or(OsStr::new(""));
292+
completions.extend(
293+
complete_arg_value(value.to_str().ok_or(value), opt, current_dir)
294+
.into_iter()
295+
.map(|comp| {
296+
let sep = if has_equal { "=" } else { "" };
297+
comp.add_prefix(format!("-{leading_flags}{sep}"))
298+
}),
299+
);
300+
} else {
301+
completions.extend(
302+
shorts_and_visible_aliases(cmd)
303+
.into_iter()
304+
.map(|comp| comp.add_prefix(format!("-{leading_flags}"))),
305+
);
306+
}
307+
}
308+
}
309+
completions
310+
}
311+
300312
fn complete_arg_value(
301313
value: Result<&str, &OsStr>,
302314
arg: &clap::Arg,

0 commit comments

Comments
 (0)