feat: Add custom completer for cargo <TAB> to complete aliases defined in config.toml

This commit is contained in:
NOOMA-42 2025-03-20 15:04:00 +08:00
parent 662213b095
commit 7e98310bbd
No known key found for this signature in database
2 changed files with 36 additions and 4 deletions

View File

@ -11,6 +11,7 @@ use std::fmt::Write;
use super::commands; use super::commands;
use super::list_commands; use super::list_commands;
use super::user_defined_aliases;
use crate::command_prelude::*; use crate::command_prelude::*;
use crate::util::is_rustup; use crate::util::is_rustup;
use cargo::core::shell::ColorChoice; use cargo::core::shell::ColorChoice;
@ -691,11 +692,13 @@ See '<cyan,bold>cargo help</> <cyan><<command>></>' for more information on a sp
})) }))
}).collect() }).collect()
}))) })))
.add(clap_complete::engine::SubcommandCandidates::new(|| { .add(clap_complete::engine::SubcommandCandidates::new(move || {
get_toolchains_from_rustup() let mut candidates = get_toolchains_from_rustup()
.into_iter() .into_iter()
.map(|t| clap_complete::CompletionCandidate::new(t)) .map(|t| clap_complete::CompletionCandidate::new(t))
.collect() .collect::<Vec<_>>();
candidates.extend(get_alias_candidates());
candidates
})) }))
.subcommands(commands::builtin()) .subcommands(commands::builtin())
} }
@ -717,6 +720,35 @@ fn get_toolchains_from_rustup() -> Vec<String> {
stdout.lines().map(|line| format!("+{}", line)).collect() stdout.lines().map(|line| format!("+{}", line)).collect()
} }
fn get_alias_candidates() -> Vec<clap_complete::CompletionCandidate> {
if let Ok(gctx) = new_gctx_for_completions() {
let alias_map = user_defined_aliases(&gctx);
return alias_map
.iter()
.map(|(alias, cmd_info)| {
let help_text = match cmd_info {
CommandInfo::Alias { target } => {
let cmd_str = target
.iter()
.map(String::as_str)
.collect::<Vec<_>>()
.join(" ");
format!("alias for {}", cmd_str)
}
CommandInfo::BuiltIn { .. } => {
unreachable!("BuiltIn command shouldn't appear in alias map")
}
CommandInfo::External { .. } => {
unreachable!("External command shouldn't appear in alias map")
}
};
clap_complete::CompletionCandidate::new(alias.clone()).help(Some(help_text.into()))
})
.collect();
}
Vec::new()
}
#[test] #[test]
fn verify_cli() { fn verify_cli() {
let gctx = GlobalContext::default().unwrap(); let gctx = GlobalContext::default().unwrap();

View File

@ -1341,7 +1341,7 @@ fn get_packages() -> CargoResult<Vec<Package>> {
Ok(packages) Ok(packages)
} }
fn new_gctx_for_completions() -> CargoResult<GlobalContext> { pub fn new_gctx_for_completions() -> CargoResult<GlobalContext> {
let cwd = std::env::current_dir()?; let cwd = std::env::current_dir()?;
let mut gctx = GlobalContext::new(shell::Shell::new(), cwd.clone(), cargo_home_with_cwd(&cwd)?); let mut gctx = GlobalContext::new(shell::Shell::new(), cwd.clone(), cargo_home_with_cwd(&cwd)?);