@@ -25,7 +25,6 @@ use clap::builder::UnknownArgumentValueParser;
25
25
use home:: cargo_home_with_cwd;
26
26
use semver:: Version ;
27
27
use std:: collections:: HashMap ;
28
- use std:: collections:: HashSet ;
29
28
use std:: ffi:: { OsStr , OsString } ;
30
29
use std:: path:: Path ;
31
30
use std:: path:: PathBuf ;
@@ -1129,53 +1128,40 @@ pub fn get_registry_candidates() -> CargoResult<Vec<clap_complete::CompletionCan
1129
1128
1130
1129
fn get_feature_candidates ( ) -> CargoResult < Vec < clap_complete:: CompletionCandidate > > {
1131
1130
let gctx = new_gctx_for_completions ( ) ?;
1131
+ let manifest_path = find_root_manifest_for_wd ( gctx. cwd ( ) ) ?;
1132
+ let ws = Workspace :: new ( & manifest_path, & gctx) ?;
1133
+ let mut feature_candidates = Vec :: new ( ) ;
1132
1134
1133
- let manifest_path = match find_root_manifest_for_wd ( gctx. cwd ( ) ) {
1134
- Ok ( path) => path,
1135
- Err ( _) => return Ok ( Vec :: new ( ) ) ,
1136
- } ;
1137
- let ws = match Workspace :: new ( & manifest_path, & gctx) {
1138
- Ok ( ws) => ws,
1139
- Err ( _) => return Ok ( Vec :: new ( ) ) ,
1140
- } ;
1141
-
1142
- let mut features = HashSet :: new ( ) ;
1143
-
1144
- // Process all packages in the workspace, collect features from all packages since --package could be used to select any of them
1135
+ // Process all packages in the workspace
1145
1136
for package in ws. members ( ) {
1137
+ let package_name = package. name ( ) ;
1138
+
1139
+ // Add direct features with package info
1146
1140
for feature_name in package. summary ( ) . features ( ) . keys ( ) {
1147
- features. insert ( feature_name. as_str ( ) . to_string ( ) ) ;
1148
- }
1149
-
1150
- // Add optional dependencies as they can be enabled as features, these might not be in the features map if they are not explicitly referenced
1151
- for dep in package. dependencies ( ) {
1152
- if dep. is_optional ( ) {
1153
- features. insert ( dep. name_in_toml ( ) . to_string ( ) ) ;
1154
- }
1141
+ feature_candidates. push (
1142
+ clap_complete:: CompletionCandidate :: new ( feature_name)
1143
+ . help ( Some ( format ! ( "(from {})" , package_name) . into ( ) ) )
1144
+ ) ;
1155
1145
}
1156
-
1146
+
1157
1147
// Add qualified features for dependencies
1158
1148
for dep in package. dependencies ( ) {
1159
- let dep_name = dep. package_name ( ) . as_str ( ) . to_string ( ) ;
1160
- // try to find this dependency in the workspace
1161
- if let Some ( dep_pkg) = ws. members ( ) . find ( |p| p. name ( ) . as_str ( ) == dep_name) {
1149
+ let dep_name = dep. name_in_toml ( ) ;
1150
+
1151
+ // Try to find this dependency in the workspace
1152
+ if let Some ( dep_pkg) = ws. members ( ) . find ( |p| p. name ( ) == dep_name) {
1162
1153
for feat in dep_pkg. summary ( ) . features ( ) . keys ( ) {
1163
- features. insert ( format ! ( "{}/{}" , dep_name, feat) ) ;
1154
+ let qualified_name = format ! ( "{}/{}" , dep_name, feat) ;
1155
+ feature_candidates. push (
1156
+ clap_complete:: CompletionCandidate :: new ( qualified_name)
1157
+ . help ( Some ( format ! ( "(from {})" , dep_pkg. name( ) ) . into ( ) ) )
1158
+ ) ;
1164
1159
}
1165
1160
}
1166
1161
}
1167
1162
}
1168
-
1169
- // always include the default feature
1170
- features. insert ( "default" . to_string ( ) ) ;
1171
-
1172
- let mut sorted_features: Vec < _ > = features. into_iter ( ) . collect ( ) ;
1173
- sorted_features. sort ( ) ;
1174
-
1175
- Ok ( sorted_features
1176
- . into_iter ( )
1177
- . map ( |name| clap_complete:: CompletionCandidate :: new ( name) )
1178
- . collect ( ) )
1163
+
1164
+ Ok ( feature_candidates)
1179
1165
}
1180
1166
1181
1167
fn get_profile_candidates ( ) -> Vec < clap_complete:: CompletionCandidate > {
0 commit comments