@@ -23,11 +23,12 @@ use cargo_util_schemas::manifest::ProfileName;
2323use cargo_util_schemas:: manifest:: RegistryName ;
2424use cargo_util_schemas:: manifest:: StringOrVec ;
2525use clap:: builder:: UnknownArgumentValueParser ;
26+ use clap_complete:: ArgValueCandidates ;
2627use home:: cargo_home_with_cwd;
2728use indexmap:: IndexSet ;
2829use itertools:: Itertools ;
2930use semver:: Version ;
30- use std:: collections:: { HashMap , HashSet } ;
31+ use std:: collections:: { BTreeMap , HashMap , HashSet } ;
3132use std:: ffi:: { OsStr , OsString } ;
3233use std:: path:: Path ;
3334use std:: path:: PathBuf ;
@@ -60,7 +61,13 @@ pub trait CommandExt: Sized {
6061 all : & ' static str ,
6162 exclude : & ' static str ,
6263 ) -> Self {
63- self . arg_package_spec_no_all ( package, all, exclude) . _arg (
64+ self . arg_package_spec_no_all (
65+ package,
66+ all,
67+ exclude,
68+ ArgValueCandidates :: new ( get_ws_member_candidates) ,
69+ )
70+ . _arg (
6471 flag ( "all" , "Alias for --workspace (deprecated)" )
6572 . help_heading ( heading:: PACKAGE_SELECTION ) ,
6673 )
@@ -74,6 +81,7 @@ pub trait CommandExt: Sized {
7481 package : & ' static str ,
7582 all : & ' static str ,
7683 exclude : & ' static str ,
84+ package_completion : ArgValueCandidates ,
7785 ) -> Self {
7886 let unsupported_short_arg = {
7987 let value_parser = UnknownArgumentValueParser :: suggest_arg ( "--exclude" ) ;
@@ -84,17 +92,28 @@ pub trait CommandExt: Sized {
8492 . action ( ArgAction :: SetTrue )
8593 . hide ( true )
8694 } ;
87- self . arg_package_spec_simple ( package)
95+ self . arg_package_spec_simple ( package, package_completion )
8896 . _arg ( flag ( "workspace" , all) . help_heading ( heading:: PACKAGE_SELECTION ) )
89- . _arg ( multi_opt ( "exclude" , "SPEC" , exclude) . help_heading ( heading:: PACKAGE_SELECTION ) )
97+ . _arg (
98+ multi_opt ( "exclude" , "SPEC" , exclude)
99+ . help_heading ( heading:: PACKAGE_SELECTION )
100+ . add ( clap_complete:: ArgValueCandidates :: new (
101+ get_ws_member_candidates,
102+ ) ) ,
103+ )
90104 . _arg ( unsupported_short_arg)
91105 }
92106
93- fn arg_package_spec_simple ( self , package : & ' static str ) -> Self {
107+ fn arg_package_spec_simple (
108+ self ,
109+ package : & ' static str ,
110+ package_completion : ArgValueCandidates ,
111+ ) -> Self {
94112 self . _arg (
95113 optional_multi_opt ( "package" , "SPEC" , package)
96114 . short ( 'p' )
97- . help_heading ( heading:: PACKAGE_SELECTION ) ,
115+ . help_heading ( heading:: PACKAGE_SELECTION )
116+ . add ( package_completion) ,
98117 )
99118 }
100119
@@ -103,7 +122,10 @@ pub trait CommandExt: Sized {
103122 optional_opt ( "package" , package)
104123 . short ( 'p' )
105124 . value_name ( "SPEC" )
106- . help_heading ( heading:: PACKAGE_SELECTION ) ,
125+ . help_heading ( heading:: PACKAGE_SELECTION )
126+ . add ( clap_complete:: ArgValueCandidates :: new ( || {
127+ get_ws_member_candidates ( )
128+ } ) ) ,
107129 )
108130 }
109131
@@ -1313,6 +1335,29 @@ fn get_target_triples_from_rustc() -> CargoResult<Vec<clap_complete::CompletionC
13131335 . collect ( ) )
13141336}
13151337
1338+ pub fn get_ws_member_candidates ( ) -> Vec < clap_complete:: CompletionCandidate > {
1339+ get_ws_member_packages ( )
1340+ . unwrap_or_default ( )
1341+ . into_iter ( )
1342+ . map ( |pkg| {
1343+ clap_complete:: CompletionCandidate :: new ( pkg. name ( ) . as_str ( ) ) . help (
1344+ pkg. manifest ( )
1345+ . metadata ( )
1346+ . description
1347+ . to_owned ( )
1348+ . map ( From :: from) ,
1349+ )
1350+ } )
1351+ . collect :: < Vec < _ > > ( )
1352+ }
1353+
1354+ fn get_ws_member_packages ( ) -> CargoResult < Vec < Package > > {
1355+ let gctx = new_gctx_for_completions ( ) ?;
1356+ let ws = Workspace :: new ( & find_root_manifest_for_wd ( gctx. cwd ( ) ) ?, & gctx) ?;
1357+ let packages = ws. members ( ) . map ( Clone :: clone) . collect :: < Vec < _ > > ( ) ;
1358+ Ok ( packages)
1359+ }
1360+
13161361pub fn get_pkg_id_spec_candidates ( ) -> Vec < clap_complete:: CompletionCandidate > {
13171362 let mut candidates = vec ! [ ] ;
13181363
@@ -1400,6 +1445,26 @@ pub fn get_pkg_id_spec_candidates() -> Vec<clap_complete::CompletionCandidate> {
14001445 candidates
14011446}
14021447
1448+ pub fn get_pkg_name_candidates ( ) -> Vec < clap_complete:: CompletionCandidate > {
1449+ let packages: BTreeMap < _ , _ > = get_packages ( )
1450+ . unwrap_or_default ( )
1451+ . into_iter ( )
1452+ . map ( |package| {
1453+ (
1454+ package. name ( ) ,
1455+ package. manifest ( ) . metadata ( ) . description . clone ( ) ,
1456+ )
1457+ } )
1458+ . collect ( ) ;
1459+
1460+ packages
1461+ . into_iter ( )
1462+ . map ( |( name, description) | {
1463+ clap_complete:: CompletionCandidate :: new ( name. as_str ( ) ) . help ( description. map ( From :: from) )
1464+ } )
1465+ . collect ( )
1466+ }
1467+
14031468fn get_packages ( ) -> CargoResult < Vec < Package > > {
14041469 let gctx = new_gctx_for_completions ( ) ?;
14051470
0 commit comments