@@ -22,17 +22,9 @@ pub fn cli() -> Command {
2222 Arg :: new ( "COMMAND" )
2323 . num_args ( 1 ..)
2424 . action ( ArgAction :: Append )
25- . add ( clap_complete:: ArgValueCandidates :: new ( || {
26- super :: builtin ( )
27- . iter ( )
28- . map ( |cmd| {
29- let name = cmd. get_name ( ) ;
30- clap_complete:: CompletionCandidate :: new ( name)
31- . help ( cmd. get_about ( ) . cloned ( ) )
32- . hide ( cmd. is_hide_set ( ) )
33- } )
34- . collect ( )
35- } ) ) ,
25+ . add ( clap_complete:: ArgValueCandidates :: new (
26+ get_completion_candidates,
27+ ) ) ,
3628 )
3729}
3830
@@ -240,3 +232,34 @@ fn all_builtin_commands() -> HashMap<String, ManPageLookup> {
240232
241233 map
242234}
235+
236+ /// Returns dash-joined names for nested commands,
237+ /// so they can be completed as single tokens.
238+ fn get_completion_candidates ( ) -> Vec < clap_complete:: CompletionCandidate > {
239+ fn walk (
240+ cmd : Command ,
241+ prefix : Option < & String > ,
242+ candidates : & mut Vec < clap_complete:: CompletionCandidate > ,
243+ ) {
244+ let name = cmd. get_name ( ) ;
245+ let key = match prefix {
246+ Some ( prefix) => format ! ( "{prefix}-{name}" ) ,
247+ None => name. to_string ( ) ,
248+ } ;
249+
250+ for cmd in cmd. get_subcommands ( ) {
251+ walk ( cmd. clone ( ) , Some ( & key) , candidates) ;
252+ }
253+
254+ let candidate = clap_complete:: CompletionCandidate :: new ( & key)
255+ . help ( cmd. get_about ( ) . cloned ( ) )
256+ . hide ( cmd. is_hide_set ( ) ) ;
257+ candidates. push ( candidate) ;
258+ }
259+
260+ let mut candidates = Vec :: new ( ) ;
261+ for cmd in super :: builtin ( ) {
262+ walk ( cmd, None , & mut candidates) ;
263+ }
264+ candidates
265+ }
0 commit comments