From 845bb8b79d6713d4017a95509e78bacbf773b025 Mon Sep 17 00:00:00 2001 From: shannmu Date: Tue, 8 Oct 2024 17:37:43 +0800 Subject: [PATCH 1/2] feat: Add `_name` to distinguish the same flags of different subcommands during compile time. --- src/cargo/util/command_prelude.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cargo/util/command_prelude.rs b/src/cargo/util/command_prelude.rs index 247143319f9..b657b21df63 100644 --- a/src/cargo/util/command_prelude.rs +++ b/src/cargo/util/command_prelude.rs @@ -48,6 +48,8 @@ pub mod heading { pub trait CommandExt: Sized { fn _arg(self, arg: Arg) -> Self; + fn _name(&self) -> String; + /// Do not use this method, it is only for backwards compatibility. /// Use `arg_package_spec_no_all` instead. fn arg_package_spec( @@ -480,6 +482,10 @@ impl CommandExt for Command { fn _arg(self, arg: Arg) -> Self { self.arg(arg) } + + fn _name(&self) -> String { + self.get_name().to_string() + } } pub fn flag(name: &'static str, help: &'static str) -> Arg { From 2bac0b69e9eebdcbbfc910154e8b174609f1463a Mon Sep 17 00:00:00 2001 From: shannmu Date: Tue, 17 Sep 2024 16:14:44 +0800 Subject: [PATCH 2/2] feat: Add custom completer for completing `cargo build --packge ` / `cargo tree --package ` --- src/cargo/util/command_prelude.rs | 40 +++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/cargo/util/command_prelude.rs b/src/cargo/util/command_prelude.rs index b657b21df63..6d10f8290d0 100644 --- a/src/cargo/util/command_prelude.rs +++ b/src/cargo/util/command_prelude.rs @@ -89,10 +89,18 @@ pub trait CommandExt: Sized { } fn arg_package_spec_simple(self, package: &'static str) -> Self { + let name = self._name(); self._arg( optional_multi_opt("package", "SPEC", package) .short('p') - .help_heading(heading::PACKAGE_SELECTION), + .help_heading(heading::PACKAGE_SELECTION) + .add(clap_complete::ArgValueCandidates::new(move || { + if ["build", "tree"].contains(&name.as_str()) { + get_ws_member_candidates() + } else { + vec![] + } + })), ) } @@ -101,7 +109,10 @@ pub trait CommandExt: Sized { optional_opt("package", package) .short('p') .value_name("SPEC") - .help_heading(heading::PACKAGE_SELECTION), + .help_heading(heading::PACKAGE_SELECTION) + .add(clap_complete::ArgValueCandidates::new( + get_ws_member_candidates, + )), ) } @@ -1304,6 +1315,31 @@ fn get_packages() -> CargoResult> { Ok(packages) } +fn get_ws_member_candidates() -> Vec { + get_ws_member_packages() + .unwrap_or_default() + .into_iter() + .map(|pkg| { + clap_complete::CompletionCandidate::new(pkg.name().as_str()).help( + pkg.manifest() + .metadata() + .description + .to_owned() + .map(From::from), + ) + }) + .collect::>() +} + +fn get_ws_member_packages() -> CargoResult> { + let gctx = new_gctx_for_completions()?; + let ws = Workspace::new(&find_root_manifest_for_wd(gctx.cwd())?, &gctx)?; + + let packages = ws.members().map(|pkg| pkg.to_owned()).collect::>(); + + Ok(packages) +} + fn new_gctx_for_completions() -> CargoResult { let cwd = std::env::current_dir()?; let mut gctx = GlobalContext::new(shell::Shell::new(), cwd.clone(), cargo_home_with_cwd(&cwd)?);