@@ -59,7 +59,7 @@ type Command struct {
59
59
Middleware MiddlewareFunc
60
60
Handler HandlerFunc
61
61
HelpHandler HandlerFunc
62
- // CompletionHandler is called when the command is run is completion
62
+ // CompletionHandler is called when the command is run in completion
63
63
// mode. If nil, only the default completion handler is used.
64
64
//
65
65
// Flag and option parsing is best-effort in this mode, so even if an Option
@@ -187,7 +187,6 @@ func (c *Command) Invoke(args ...string) *Invocation {
187
187
return & Invocation {
188
188
Command : c ,
189
189
Args : args ,
190
- AllArgs : args ,
191
190
Stdout : io .Discard ,
192
191
Stderr : io .Discard ,
193
192
Stdin : strings .NewReader ("" ),
@@ -204,9 +203,6 @@ type Invocation struct {
204
203
// Args is reduced into the remaining arguments after parsing flags
205
204
// during Run.
206
205
Args []string
207
- // AllArgs is the original arguments passed to the command, including flags.
208
- // When invoked `WithOS`, this includes argv[0], otherwise it is the same as Args.
209
- AllArgs []string
210
206
// CurWord is the word the terminal cursor is currently in
211
207
CurWord string
212
208
@@ -233,7 +229,6 @@ func (inv *Invocation) WithOS() *Invocation {
233
229
i .Stdout = os .Stdout
234
230
i .Stderr = os .Stderr
235
231
i .Stdin = os .Stdin
236
- i .AllArgs = os .Args
237
232
i .Args = os .Args [1 :]
238
233
i .Environ = ParseEnviron (os .Environ (), "" )
239
234
i .Net = osNet {}
@@ -302,13 +297,13 @@ func copyFlagSetWithout(fs *pflag.FlagSet, without string) *pflag.FlagSet {
302
297
return fs2
303
298
}
304
299
305
- func (inv * Invocation ) GetCurWords () (prev string , cur string ) {
306
- if len (inv .AllArgs ) == 1 {
307
- cur = inv .AllArgs [0 ]
300
+ func (inv * Invocation ) curWords () (prev string , cur string ) {
301
+ if len (inv .Args ) == 1 {
302
+ cur = inv .Args [0 ]
308
303
prev = ""
309
304
} else {
310
- cur = inv .AllArgs [len (inv .AllArgs )- 1 ]
311
- prev = inv .AllArgs [len (inv .AllArgs )- 2 ]
305
+ cur = inv .Args [len (inv .Args )- 1 ]
306
+ prev = inv .Args [len (inv .Args )- 2 ]
312
307
}
313
308
return
314
309
}
@@ -409,7 +404,39 @@ func (inv *Invocation) run(state *runState) error {
409
404
}
410
405
}
411
406
412
- ignoreFlagParseErrors := inv .Command .RawArgs || inv .IsCompletionMode ()
407
+ // Outputted completions are not filtered based on the word under the cursor, as every shell we support does this already.
408
+ // We only look at the current word to figure out handler to run, or what directory to inspect.
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 )
435
+ }
436
+ return nil
437
+ }
438
+
439
+ ignoreFlagParseErrors := inv .Command .RawArgs
413
440
414
441
// Flag parse errors are irrelevant for raw args commands.
415
442
if ! ignoreFlagParseErrors && state .flagParseErr != nil && ! errors .Is (state .flagParseErr , pflag .ErrHelp ) {
@@ -464,39 +491,6 @@ func (inv *Invocation) run(state *runState) error {
464
491
defer cancel ()
465
492
inv = inv .WithContext (ctx )
466
493
467
- // Outputted completions are not filtered based on the word under the cursor, as every shell we support does this already.
468
- // We only look at the current word to figure out handler to run, or what directory to inspect.
469
- if inv .IsCompletionMode () {
470
- prev , cur := inv .GetCurWords ()
471
- inv .CurWord = cur
472
- // If the current word is a flag set using `=`, use it's handler
473
- if strings .HasPrefix (cur , "--" ) && strings .Contains (cur , "=" ) {
474
- if inv .equalsFlagHandler (cur ) {
475
- return nil
476
- }
477
- }
478
- // If the previous word is a flag, then we're writing it's value
479
- // and we should check it's handler
480
- if strings .HasPrefix (prev , "--" ) {
481
- if inv .flagHandler (prev ) {
482
- return nil
483
- }
484
- }
485
- if inv .Command .Name () == inv .CurWord {
486
- fmt .Fprintf (inv .Stdout , "%s\n " , inv .Command .Name ())
487
- return nil
488
- }
489
- if inv .Command .CompletionHandler != nil {
490
- for _ , e := range inv .Command .CompletionHandler (inv ) {
491
- fmt .Fprintf (inv .Stdout , "%s\n " , e )
492
- }
493
- }
494
- for _ , e := range DefaultCompletionHandler (inv ) {
495
- fmt .Fprintf (inv .Stdout , "%s\n " , e )
496
- }
497
- return nil
498
- }
499
-
500
494
if inv .Command .Handler == nil || errors .Is (state .flagParseErr , pflag .ErrHelp ) {
501
495
if inv .Command .HelpHandler == nil {
502
496
return defaultHelpFn ()(inv )
@@ -743,5 +737,3 @@ func RequireRangeArgs(start, end int) MiddlewareFunc {
743
737
type HandlerFunc func (i * Invocation ) error
744
738
745
739
type CompletionHandlerFunc func (i * Invocation ) []string
746
-
747
- var NopHandler HandlerFunc = func (i * Invocation ) error { return nil }
0 commit comments