Skip to content

Commit

Permalink
feat: Add custom completer for completing example names
Browse files Browse the repository at this point in the history
  • Loading branch information
shannmu committed Sep 11, 2024
1 parent e7ca9be commit 7f75178
Showing 1 changed file with 43 additions and 3 deletions.
46 changes: 43 additions & 3 deletions src/cargo/util/command_prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,10 @@ pub trait CommandExt: Sized {
._arg(flag("examples", examples).help_heading(heading::TARGET_SELECTION))
._arg(
optional_multi_opt("example", "NAME", example)
.help_heading(heading::TARGET_SELECTION),
.help_heading(heading::TARGET_SELECTION)
.add(clap_complete::ArgValueCandidates::new(
get_examples_candidates,
)),
)
}

Expand All @@ -192,7 +195,10 @@ pub trait CommandExt: Sized {
._arg(flag("bins", bins).help_heading(heading::TARGET_SELECTION))
._arg(
optional_multi_opt("example", "NAME", example)
.help_heading(heading::TARGET_SELECTION),
.help_heading(heading::TARGET_SELECTION)
.add(clap_complete::ArgValueCandidates::new(
get_examples_candidates,
)),
)
._arg(flag("examples", examples).help_heading(heading::TARGET_SELECTION))
}
Expand All @@ -201,7 +207,10 @@ pub trait CommandExt: Sized {
self._arg(optional_multi_opt("bin", "NAME", bin).help_heading(heading::TARGET_SELECTION))
._arg(
optional_multi_opt("example", "NAME", example)
.help_heading(heading::TARGET_SELECTION),
.help_heading(heading::TARGET_SELECTION)
.add(clap_complete::ArgValueCandidates::new(
get_examples_candidates,
)),
)
}

Expand Down Expand Up @@ -1027,6 +1036,37 @@ pub fn lockfile_path(
return Ok(Some(path));
}

fn get_examples_candidates() -> Vec<clap_complete::CompletionCandidate> {
match get_examples_from_cwd() {
Ok(examples) => examples
.into_iter()
.map(|example| clap_complete::CompletionCandidate::new(example))
.collect(),
Err(_) => vec![],
}
}

fn get_examples_from_cwd() -> CargoResult<Vec<OsString>> {
let mut examples = vec![];

let example_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("examples");

for example in example_path.read_dir()? {
let example = example?;
if !example.file_type()?.is_file() {
continue;
}

if let Some(name) = example.file_name().to_str() {
if name.ends_with(".rs") {
examples.push(name.into());
}
}
}

Ok(examples)
}

#[track_caller]
pub fn ignore_unknown<T: Default>(r: Result<T, clap::parser::MatchesError>) -> T {
match r {
Expand Down

0 comments on commit 7f75178

Please sign in to comment.