Skip to content

Commit 10eaf34

Browse files
committed
Auto merge of #14535 - shannmu:_cargo_target_triple, r=epage
feat: Add custom completer for completing target triple ### What does this PR try to resolve? Tracking issue #14520 Add custom completer for `cargo build --target=<TAB>`
2 parents 75ab4e5 + 7968f54 commit 10eaf34

File tree

1 file changed

+58
-1
lines changed

1 file changed

+58
-1
lines changed

src/cargo/util/command_prelude.rs

+58-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ pub trait CommandExt: Sized {
272272
};
273273
self._arg(
274274
optional_multi_opt("target", "TRIPLE", target)
275-
.help_heading(heading::COMPILATION_OPTIONS),
275+
.help_heading(heading::COMPILATION_OPTIONS)
276+
.add(clap_complete::ArgValueCandidates::new(get_target_triples)),
276277
)
277278
._arg(unsupported_short_arg)
278279
}
@@ -1067,6 +1068,62 @@ fn get_targets_from_metadata() -> CargoResult<Vec<Target>> {
10671068
Ok(targets)
10681069
}
10691070

1071+
fn get_target_triples() -> Vec<clap_complete::CompletionCandidate> {
1072+
let mut candidates = Vec::new();
1073+
1074+
if is_rustup() {
1075+
if let Ok(targets) = get_target_triples_from_rustup() {
1076+
candidates.extend(targets);
1077+
}
1078+
} else {
1079+
if let Ok(targets) = get_target_triples_from_rustc() {
1080+
candidates.extend(targets);
1081+
}
1082+
}
1083+
1084+
candidates
1085+
}
1086+
1087+
fn get_target_triples_from_rustup() -> CargoResult<Vec<clap_complete::CompletionCandidate>> {
1088+
let output = std::process::Command::new("rustup")
1089+
.arg("target")
1090+
.arg("list")
1091+
.output()?;
1092+
1093+
if !output.status.success() {
1094+
return Ok(vec![]);
1095+
}
1096+
1097+
let stdout = String::from_utf8(output.stdout)?;
1098+
1099+
Ok(stdout
1100+
.lines()
1101+
.map(|line| {
1102+
let target = line.split_once(' ');
1103+
match target {
1104+
None => clap_complete::CompletionCandidate::new(line.to_owned()).hide(true),
1105+
Some((target, _installed)) => clap_complete::CompletionCandidate::new(target),
1106+
}
1107+
})
1108+
.collect())
1109+
}
1110+
1111+
fn get_target_triples_from_rustc() -> CargoResult<Vec<clap_complete::CompletionCandidate>> {
1112+
let cwd = std::env::current_dir()?;
1113+
let gctx = GlobalContext::new(shell::Shell::new(), cwd.clone(), cargo_home_with_cwd(&cwd)?);
1114+
let ws = Workspace::new(&find_root_manifest_for_wd(&PathBuf::from(&cwd))?, &gctx);
1115+
1116+
let rustc = gctx.load_global_rustc(ws.as_ref().ok())?;
1117+
1118+
let (stdout, _stderr) =
1119+
rustc.cached_output(rustc.process().arg("--print").arg("target-list"), 0)?;
1120+
1121+
Ok(stdout
1122+
.lines()
1123+
.map(|line| clap_complete::CompletionCandidate::new(line.to_owned()))
1124+
.collect())
1125+
}
1126+
10701127
#[track_caller]
10711128
pub fn ignore_unknown<T: Default>(r: Result<T, clap::parser::MatchesError>) -> T {
10721129
match r {

0 commit comments

Comments
 (0)