@@ -407,31 +407,8 @@ func (inv *Invocation) run(state *runState) error {
407
407
// Outputted completions are not filtered based on the word under the cursor, as every shell we support does this already.
408
408
// We only look at the current word to figure out handler to run, or what directory to inspect.
409
409
if inv .IsCompletionMode () {
410
- prev , cur := inv .curWords ()
411
- inv .CurWord = cur
412
- // If the current word is a flag set using `=`, use it's handler
413
- if strings .HasPrefix (cur , "--" ) && strings .Contains (cur , "=" ) {
414
- if inv .equalsFlagHandler (cur ) {
415
- return nil
416
- }
417
- }
418
- // If the previous word is a flag, then we're writing it's value
419
- // and we should check it's handler
420
- if strings .HasPrefix (prev , "--" ) {
421
- if inv .flagHandler (prev ) {
422
- return nil
423
- }
424
- }
425
- // If the current word is the command, auto-complete it so the shell moves the cursor
426
- if inv .Command .Name () == inv .CurWord {
427
- fmt .Fprintf (inv .Stdout , "%s\n " , inv .Command .Name ())
428
- return nil
429
- }
430
- if inv .Command .CompletionHandler == nil {
431
- inv .Command .CompletionHandler = DefaultCompletionHandler
432
- }
433
- for _ , e := range inv .Command .CompletionHandler (inv ) {
434
- fmt .Fprintf (inv .Stdout , "%s\n " , e )
410
+ for _ , e := range inv .doCompletions () {
411
+ fmt .Fprintln (inv .Stdout , e )
435
412
}
436
413
return nil
437
414
}
@@ -613,11 +590,42 @@ func (inv *Invocation) with(fn func(*Invocation)) *Invocation {
613
590
return & i2
614
591
}
615
592
616
- func (inv * Invocation ) flagHandler (word string ) bool {
617
- return inv .doFlagCompletion ("" , word )
593
+ func (inv * Invocation ) doCompletions () []string {
594
+ prev , cur := inv .curWords ()
595
+ inv .CurWord = cur
596
+ // If the current word is a flag set using `=`, use it's handler
597
+ if strings .HasPrefix (cur , "--" ) && strings .Contains (cur , "=" ) {
598
+ if out := inv .equalsFlagCompletions (cur ); out != nil {
599
+ return out
600
+ }
601
+ }
602
+ // If the previous word is a flag, then we're writing it's value
603
+ // and we should check it's handler
604
+ if strings .HasPrefix (prev , "--" ) {
605
+ if out := inv .flagCompletions (prev ); out != nil {
606
+ return out
607
+ }
608
+ }
609
+ // If the current word is the command, auto-complete it so the shell moves the cursor
610
+ if inv .Command .Name () == inv .CurWord {
611
+ return []string {inv .Command .Name ()}
612
+ }
613
+ var completions []string
614
+
615
+ if inv .Command .CompletionHandler != nil {
616
+ completions = append (completions , inv .Command .CompletionHandler (inv )... )
617
+ }
618
+
619
+ completions = append (completions , DefaultCompletionHandler (inv )... )
620
+
621
+ return completions
618
622
}
619
623
620
- func (inv * Invocation ) equalsFlagHandler (word string ) bool {
624
+ func (inv * Invocation ) flagCompletions (word string ) []string {
625
+ return inv .doFlagCompletions ("" , word )
626
+ }
627
+
628
+ func (inv * Invocation ) equalsFlagCompletions (word string ) []string {
621
629
words := strings .Split (word , "=" )
622
630
word = words [0 ]
623
631
if len (words ) > 1 {
@@ -626,29 +634,32 @@ func (inv *Invocation) equalsFlagHandler(word string) bool {
626
634
inv .CurWord = ""
627
635
}
628
636
prefix := word + "="
629
- return inv .doFlagCompletion (prefix , word )
637
+ return inv .doFlagCompletions (prefix , word )
630
638
}
631
639
632
- func (inv * Invocation ) doFlagCompletion (prefix , word string ) bool {
640
+ func (inv * Invocation ) doFlagCompletions (prefix , word string ) [] string {
633
641
opt := inv .Command .Options .ByFlag (word [2 :])
634
642
if opt == nil {
635
- return false
643
+ return nil
636
644
}
637
645
if opt .CompletionHandler != nil {
638
646
completions := opt .CompletionHandler (inv )
647
+ out := make ([]string , 0 , len (completions ))
639
648
for _ , completion := range completions {
640
- fmt . Fprintf ( inv . Stdout , "%s%s\n " , prefix , completion )
649
+ out = append ( out , fmt . Sprintf ( "%s%s" , prefix , completion ) )
641
650
}
642
- return true
651
+ return out
643
652
}
644
653
val , ok := opt .Value .(* Enum )
645
654
if ok {
646
- for _ , choice := range val .Choices {
647
- fmt .Fprintf (inv .Stdout , "%s%s\n " , prefix , choice )
655
+ completions := val .Choices
656
+ out := make ([]string , 0 , len (completions ))
657
+ for _ , choice := range completions {
658
+ out = append (out , fmt .Sprintf ("%s%s" , prefix , choice ))
648
659
}
649
- return true
660
+ return out
650
661
}
651
- return false
662
+ return nil
652
663
}
653
664
654
665
// MiddlewareFunc returns the next handler in the chain,
0 commit comments