From 954581bdfb5c3c80b979a6d77e594fa6d14147d8 Mon Sep 17 00:00:00 2001 From: shannmu Date: Mon, 12 Aug 2024 22:13:55 +0800 Subject: [PATCH] feat: Add custom completer for completing installed binaries --- src/bin/cargo/commands/uninstall.rs | 31 ++++++++++++++++++++++++++++- src/cargo/ops/mod.rs | 1 + 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/bin/cargo/commands/uninstall.rs b/src/bin/cargo/commands/uninstall.rs index cad538de9c0..d50996d9af6 100644 --- a/src/bin/cargo/commands/uninstall.rs +++ b/src/bin/cargo/commands/uninstall.rs @@ -5,7 +5,14 @@ use cargo::ops; pub fn cli() -> Command { subcommand("uninstall") .about("Remove a Rust binary") - .arg(Arg::new("spec").value_name("SPEC").num_args(0..)) + .arg( + Arg::new("spec") + .value_name("SPEC") + .num_args(0..) + .add::(clap_complete::ArgValueCandidates::new( + || get_installed_crates(), + )), + ) .arg(opt("root", "Directory to uninstall packages from").value_name("DIR")) .arg_silent_suggestion() .arg_package_spec_simple("Package to uninstall") @@ -37,3 +44,25 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult { ops::uninstall(root, specs, &values(args, "bin"), gctx)?; Ok(()) } + +fn get_installed_crates() -> Vec { + get_installed_crates_().unwrap_or_default() +} + +fn get_installed_crates_() -> Option> { + let mut candidates = Vec::new(); + + let gctx = GlobalContext::default().ok()?; + + let root = ops::resolve_root(None, &gctx).ok()?; + + let tracker = ops::InstallTracker::load(&gctx, &root).ok()?; + + for (_, v) in tracker.all_installed_bins() { + for bin in v { + candidates.push(clap_complete::CompletionCandidate::new(bin)); + } + } + + Some(candidates) +} diff --git a/src/cargo/ops/mod.rs b/src/cargo/ops/mod.rs index 2075c9ccc4c..7d35f952995 100644 --- a/src/cargo/ops/mod.rs +++ b/src/cargo/ops/mod.rs @@ -22,6 +22,7 @@ pub use self::cargo_update::update_lockfile; pub use self::cargo_update::upgrade_manifests; pub use self::cargo_update::write_manifest_upgrades; pub use self::cargo_update::UpdateOptions; +pub use self::common_for_install_and_uninstall::{resolve_root, InstallTracker}; pub use self::fix::{fix, fix_exec_rustc, fix_get_proxy_lock_addr, FixOptions}; pub use self::lockfile::{load_pkg_lockfile, resolve_to_string, write_pkg_lockfile}; pub use self::registry::info;