1
1
use crate :: core:: compiler:: { BuildConfig , MessageFormat , TimingOutput } ;
2
2
use crate :: core:: resolver:: CliFeatures ;
3
- use crate :: core:: { Edition , Workspace } ;
3
+ use crate :: core:: { shell , Edition , Target , TargetKind , Workspace } ;
4
4
use crate :: ops:: lockfile:: LOCKFILE_NAME ;
5
5
use crate :: ops:: registry:: RegistryOrIndex ;
6
6
use crate :: ops:: { CompileFilter , CompileOptions , NewOptions , Packages , VersionControl } ;
@@ -19,6 +19,7 @@ use cargo_util_schemas::manifest::ProfileName;
19
19
use cargo_util_schemas:: manifest:: RegistryName ;
20
20
use cargo_util_schemas:: manifest:: StringOrVec ;
21
21
use clap:: builder:: UnknownArgumentValueParser ;
22
+ use home:: cargo_home_with_cwd;
22
23
use std:: ffi:: { OsStr , OsString } ;
23
24
use std:: path:: Path ;
24
25
use std:: path:: PathBuf ;
@@ -173,7 +174,11 @@ pub trait CommandExt: Sized {
173
174
) -> Self {
174
175
self . _arg ( flag ( "lib" , lib) . help_heading ( heading:: TARGET_SELECTION ) )
175
176
. _arg ( flag ( "bins" , bins) . help_heading ( heading:: TARGET_SELECTION ) )
176
- . _arg ( optional_multi_opt ( "bin" , "NAME" , bin) . help_heading ( heading:: TARGET_SELECTION ) )
177
+ . _arg (
178
+ optional_multi_opt ( "bin" , "NAME" , bin)
179
+ . help_heading ( heading:: TARGET_SELECTION )
180
+ . add ( clap_complete:: ArgValueCandidates :: new ( get_bin_candidates) ) ,
181
+ )
177
182
. _arg ( flag ( "examples" , examples) . help_heading ( heading:: TARGET_SELECTION ) )
178
183
. _arg (
179
184
optional_multi_opt ( "example" , "NAME" , example)
@@ -188,21 +193,27 @@ pub trait CommandExt: Sized {
188
193
example : & ' static str ,
189
194
examples : & ' static str ,
190
195
) -> Self {
191
- self . _arg ( optional_multi_opt ( "bin" , "NAME" , bin) . help_heading ( heading:: TARGET_SELECTION ) )
192
- . _arg ( flag ( "bins" , bins) . help_heading ( heading:: TARGET_SELECTION ) )
193
- . _arg (
194
- optional_multi_opt ( "example" , "NAME" , example)
195
- . help_heading ( heading:: TARGET_SELECTION ) ,
196
- )
197
- . _arg ( flag ( "examples" , examples) . help_heading ( heading:: TARGET_SELECTION ) )
196
+ self . _arg (
197
+ optional_multi_opt ( "bin" , "NAME" , bin)
198
+ . help_heading ( heading:: TARGET_SELECTION )
199
+ . add ( clap_complete:: ArgValueCandidates :: new ( get_bin_candidates) ) ,
200
+ )
201
+ . _arg ( flag ( "bins" , bins) . help_heading ( heading:: TARGET_SELECTION ) )
202
+ . _arg (
203
+ optional_multi_opt ( "example" , "NAME" , example) . help_heading ( heading:: TARGET_SELECTION ) ,
204
+ )
205
+ . _arg ( flag ( "examples" , examples) . help_heading ( heading:: TARGET_SELECTION ) )
198
206
}
199
207
200
208
fn arg_targets_bin_example ( self , bin : & ' static str , example : & ' static str ) -> Self {
201
- self . _arg ( optional_multi_opt ( "bin" , "NAME" , bin) . help_heading ( heading:: TARGET_SELECTION ) )
202
- . _arg (
203
- optional_multi_opt ( "example" , "NAME" , example)
204
- . help_heading ( heading:: TARGET_SELECTION ) ,
205
- )
209
+ self . _arg (
210
+ optional_multi_opt ( "bin" , "NAME" , bin)
211
+ . help_heading ( heading:: TARGET_SELECTION )
212
+ . add ( clap_complete:: ArgValueCandidates :: new ( get_bin_candidates) ) ,
213
+ )
214
+ . _arg (
215
+ optional_multi_opt ( "example" , "NAME" , example) . help_heading ( heading:: TARGET_SELECTION ) ,
216
+ )
206
217
}
207
218
208
219
fn arg_features ( self ) -> Self {
@@ -333,7 +344,10 @@ pub trait CommandExt: Sized {
333
344
. value_name ( "VCS" )
334
345
. value_parser ( [ "git" , "hg" , "pijul" , "fossil" , "none" ] ) ,
335
346
)
336
- . _arg ( flag ( "bin" , "Use a binary (application) template [default]" ) )
347
+ . _arg (
348
+ flag ( "bin" , "Use a binary (application) template [default]" )
349
+ . add ( clap_complete:: ArgValueCandidates :: new ( get_bin_candidates) ) ,
350
+ )
337
351
. _arg ( flag ( "lib" , "Use a library template" ) )
338
352
. _arg (
339
353
opt ( "edition" , "Edition to set for the crate generated" )
@@ -1027,6 +1041,32 @@ pub fn lockfile_path(
1027
1041
return Ok ( Some ( path) ) ;
1028
1042
}
1029
1043
1044
+ fn get_bin_candidates ( ) -> Vec < clap_complete:: CompletionCandidate > {
1045
+ get_targets_from_metadata ( )
1046
+ . unwrap_or_default ( )
1047
+ . into_iter ( )
1048
+ . filter_map ( |target| match target. kind ( ) {
1049
+ TargetKind :: Bin => Some ( clap_complete:: CompletionCandidate :: new ( target. name ( ) ) ) ,
1050
+ _ => None ,
1051
+ } )
1052
+ . collect :: < Vec < _ > > ( )
1053
+ }
1054
+
1055
+ fn get_targets_from_metadata ( ) -> CargoResult < Vec < Target > > {
1056
+ let cwd = std:: env:: current_dir ( ) ?;
1057
+ let gctx = GlobalContext :: new ( shell:: Shell :: new ( ) , cwd. clone ( ) , cargo_home_with_cwd ( & cwd) ?) ;
1058
+ let ws = Workspace :: new ( & find_root_manifest_for_wd ( & cwd) ?, & gctx) ?;
1059
+
1060
+ let packages = ws. members ( ) . collect :: < Vec < _ > > ( ) ;
1061
+
1062
+ let targets = packages
1063
+ . into_iter ( )
1064
+ . flat_map ( |pkg| pkg. targets ( ) . into_iter ( ) . cloned ( ) )
1065
+ . collect :: < Vec < _ > > ( ) ;
1066
+
1067
+ Ok ( targets)
1068
+ }
1069
+
1030
1070
#[ track_caller]
1031
1071
pub fn ignore_unknown < T : Default > ( r : Result < T , clap:: parser:: MatchesError > ) -> T {
1032
1072
match r {
0 commit comments