@@ -139,6 +139,8 @@ type Command struct {
139139 isInError bool
140140 // track state of defaults
141141 didSetupDefaults bool
142+ // whether in shell completion mode
143+ shellCompletion bool
142144}
143145
144146// FullName returns the full name of the command.
@@ -244,7 +246,7 @@ func (cmd *Command) setupDefaults(osArgs []string) {
244246 cmd .SuggestCommandFunc = suggestCommand
245247 }
246248
247- if cmd .EnableShellCompletion {
249+ if cmd .EnableShellCompletion || cmd . Root (). shellCompletion {
248250 completionCommand := buildCompletionCommand ()
249251
250252 if cmd .ShellCompletionCommandName != "" {
@@ -346,16 +348,19 @@ func (cmd *Command) Run(ctx context.Context, osArgs []string) (deferErr error) {
346348 cmd .parent = v
347349 }
348350
349- // handle the completion flag separately from the flagset since
350- // completion could be attempted after a flag, but before its value was put
351- // on the command line. this causes the flagset to interpret the completion
352- // flag name as the value of the flag before it which is undesirable
353- // note that we can only do this because the shell autocomplete function
354- // always appends the completion flag at the end of the command
355- enableShellCompletion , osArgs := checkShellCompleteFlag (cmd , osArgs )
351+ if cmd .parent == nil {
352+ // handle the completion flag separately from the flagset since
353+ // completion could be attempted after a flag, but before its value was put
354+ // on the command line. this causes the flagset to interpret the completion
355+ // flag name as the value of the flag before it which is undesirable
356+ // note that we can only do this because the shell autocomplete function
357+ // always appends the completion flag at the end of the command
358+ tracef ("checking osArgs %v (cmd=%[2]q)" , osArgs , cmd .Name )
359+ cmd .shellCompletion , osArgs = checkShellCompleteFlag (cmd , osArgs )
356360
357- tracef ("setting cmd.EnableShellCompletion=%[1]v from checkShellCompleteFlag (cmd=%[2]q)" , enableShellCompletion , cmd .Name )
358- cmd .EnableShellCompletion = enableShellCompletion
361+ tracef ("setting cmd.shellCompletion=%[1]v from checkShellCompleteFlag (cmd=%[2]q)" , cmd .shellCompletion && cmd .EnableShellCompletion , cmd .Name )
362+ cmd .shellCompletion = cmd .EnableShellCompletion && cmd .shellCompletion
363+ }
359364
360365 tracef ("using post-checkShellCompleteFlag arguments %[1]q (cmd=%[2]q)" , osArgs , cmd .Name )
361366
@@ -418,7 +423,7 @@ func (cmd *Command) Run(ctx context.Context, osArgs []string) (deferErr error) {
418423 return nil
419424 }
420425
421- if cmd .After != nil && ! cmd .EnableShellCompletion {
426+ if cmd .After != nil && ! cmd .Root (). shellCompletion {
422427 defer func () {
423428 if err := cmd .After (ctx , cmd ); err != nil {
424429 err = cmd .handleExitCoder (ctx , err )
@@ -445,7 +450,7 @@ func (cmd *Command) Run(ctx context.Context, osArgs []string) (deferErr error) {
445450 }
446451 }
447452
448- if cmd .Before != nil && ! cmd .EnableShellCompletion {
453+ if cmd .Before != nil && ! cmd .Root (). shellCompletion {
449454 if err := cmd .Before (ctx , cmd ); err != nil {
450455 deferErr = cmd .handleExitCoder (ctx , err )
451456 return deferErr
@@ -666,7 +671,7 @@ func (cmd *Command) parseFlags(args Args) (Args, error) {
666671
667672 tracef ("parsing flags iteratively tail=%[1]q (cmd=%[2]q)" , args .Tail (), cmd .Name )
668673
669- if err := parseIter (cmd .flagSet , cmd , args .Tail (), cmd .Root ().EnableShellCompletion ); err != nil {
674+ if err := parseIter (cmd .flagSet , cmd , args .Tail (), cmd .Root ().shellCompletion ); err != nil {
670675 return cmd .Args (), err
671676 }
672677
0 commit comments