vendor/github.com/spf13/cobra/completions.go
changeset 265 05c40b36d3b2
parent 260 445e01aede7e
equal deleted inserted replaced
264:8f478162d991 265:05c40b36d3b2
       
     1 // Copyright 2013-2022 The Cobra Authors
       
     2 //
       
     3 // Licensed under the Apache License, Version 2.0 (the "License");
       
     4 // you may not use this file except in compliance with the License.
       
     5 // You may obtain a copy of the License at
       
     6 //
       
     7 //      http://www.apache.org/licenses/LICENSE-2.0
       
     8 //
       
     9 // Unless required by applicable law or agreed to in writing, software
       
    10 // distributed under the License is distributed on an "AS IS" BASIS,
       
    11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    12 // See the License for the specific language governing permissions and
       
    13 // limitations under the License.
       
    14 
     1 package cobra
    15 package cobra
     2 
    16 
     3 import (
    17 import (
     4 	"fmt"
    18 	"fmt"
     5 	"os"
    19 	"os"
   258 		// Unable to find the real command. E.g., <program> someInvalidCmd <TAB>
   272 		// Unable to find the real command. E.g., <program> someInvalidCmd <TAB>
   259 		return c, []string{}, ShellCompDirectiveDefault, fmt.Errorf("Unable to find a command for arguments: %v", trimmedArgs)
   273 		return c, []string{}, ShellCompDirectiveDefault, fmt.Errorf("Unable to find a command for arguments: %v", trimmedArgs)
   260 	}
   274 	}
   261 	finalCmd.ctx = c.ctx
   275 	finalCmd.ctx = c.ctx
   262 
   276 
       
   277 	// These flags are normally added when `execute()` is called on `finalCmd`,
       
   278 	// however, when doing completion, we don't call `finalCmd.execute()`.
       
   279 	// Let's add the --help and --version flag ourselves.
       
   280 	finalCmd.InitDefaultHelpFlag()
       
   281 	finalCmd.InitDefaultVersionFlag()
       
   282 
   263 	// Check if we are doing flag value completion before parsing the flags.
   283 	// Check if we are doing flag value completion before parsing the flags.
   264 	// This is important because if we are completing a flag value, we need to also
   284 	// This is important because if we are completing a flag value, we need to also
   265 	// remove the flag name argument from the list of finalArgs or else the parsing
   285 	// remove the flag name argument from the list of finalArgs or else the parsing
   266 	// could fail due to an invalid value (incomplete) for the flag.
   286 	// could fail due to an invalid value (incomplete) for the flag.
   267 	flag, finalArgs, toComplete, flagErr := checkIfFlagCompletion(finalCmd, finalArgs, toComplete)
   287 	flag, finalArgs, toComplete, flagErr := checkIfFlagCompletion(finalCmd, finalArgs, toComplete)
   288 	if flagErr != nil {
   308 	if flagErr != nil {
   289 		// If error type is flagCompError and we don't want flagCompletion we should ignore the error
   309 		// If error type is flagCompError and we don't want flagCompletion we should ignore the error
   290 		if _, ok := flagErr.(*flagCompError); !(ok && !flagCompletion) {
   310 		if _, ok := flagErr.(*flagCompError); !(ok && !flagCompletion) {
   291 			return finalCmd, []string{}, ShellCompDirectiveDefault, flagErr
   311 			return finalCmd, []string{}, ShellCompDirectiveDefault, flagErr
   292 		}
   312 		}
       
   313 	}
       
   314 
       
   315 	// Look for the --help or --version flags.  If they are present,
       
   316 	// there should be no further completions.
       
   317 	if helpOrVersionFlagPresent(finalCmd) {
       
   318 		return finalCmd, []string{}, ShellCompDirectiveNoFileComp, nil
   293 	}
   319 	}
   294 
   320 
   295 	// We only remove the flags from the arguments if DisableFlagParsing is not set.
   321 	// We only remove the flags from the arguments if DisableFlagParsing is not set.
   296 	// This is important for commands which have requested to do their own flag completion.
   322 	// This is important for commands which have requested to do their own flag completion.
   297 	if !finalCmd.DisableFlagParsing {
   323 	if !finalCmd.DisableFlagParsing {
   459 		comps, directive = completionFn(finalCmd, finalArgs, toComplete)
   485 		comps, directive = completionFn(finalCmd, finalArgs, toComplete)
   460 		completions = append(completions, comps...)
   486 		completions = append(completions, comps...)
   461 	}
   487 	}
   462 
   488 
   463 	return finalCmd, completions, directive, nil
   489 	return finalCmd, completions, directive, nil
       
   490 }
       
   491 
       
   492 func helpOrVersionFlagPresent(cmd *Command) bool {
       
   493 	if versionFlag := cmd.Flags().Lookup("version"); versionFlag != nil &&
       
   494 		len(versionFlag.Annotations[FlagSetByCobraAnnotation]) > 0 && versionFlag.Changed {
       
   495 		return true
       
   496 	}
       
   497 	if helpFlag := cmd.Flags().Lookup("help"); helpFlag != nil &&
       
   498 		len(helpFlag.Annotations[FlagSetByCobraAnnotation]) > 0 && helpFlag.Changed {
       
   499 		return true
       
   500 	}
       
   501 	return false
   464 }
   502 }
   465 
   503 
   466 func getFlagNameCompletions(flag *pflag.Flag, toComplete string) []string {
   504 func getFlagNameCompletions(flag *pflag.Flag, toComplete string) []string {
   467 	if nonCompletableFlag(flag) {
   505 	if nonCompletableFlag(flag) {
   468 		return []string{}
   506 		return []string{}
   605 	}
   643 	}
   606 
   644 
   607 	return flag, trimmedArgs, lastArg, nil
   645 	return flag, trimmedArgs, lastArg, nil
   608 }
   646 }
   609 
   647 
   610 // initDefaultCompletionCmd adds a default 'completion' command to c.
   648 // InitDefaultCompletionCmd adds a default 'completion' command to c.
   611 // This function will do nothing if any of the following is true:
   649 // This function will do nothing if any of the following is true:
   612 // 1- the feature has been explicitly disabled by the program,
   650 // 1- the feature has been explicitly disabled by the program,
   613 // 2- c has no subcommands (to avoid creating one),
   651 // 2- c has no subcommands (to avoid creating one),
   614 // 3- c already has a 'completion' command provided by the program.
   652 // 3- c already has a 'completion' command provided by the program.
   615 func (c *Command) initDefaultCompletionCmd() {
   653 func (c *Command) InitDefaultCompletionCmd() {
   616 	if c.CompletionOptions.DisableDefaultCmd || !c.HasSubCommands() {
   654 	if c.CompletionOptions.DisableDefaultCmd || !c.HasSubCommands() {
   617 		return
   655 		return
   618 	}
   656 	}
   619 
   657 
   620 	for _, cmd := range c.commands {
   658 	for _, cmd := range c.commands {
   633 See each sub-command's help for details on how to use the generated script.
   671 See each sub-command's help for details on how to use the generated script.
   634 `, c.Root().Name()),
   672 `, c.Root().Name()),
   635 		Args:              NoArgs,
   673 		Args:              NoArgs,
   636 		ValidArgsFunction: NoFileCompletions,
   674 		ValidArgsFunction: NoFileCompletions,
   637 		Hidden:            c.CompletionOptions.HiddenDefaultCmd,
   675 		Hidden:            c.CompletionOptions.HiddenDefaultCmd,
       
   676 		GroupID:           c.completionCommandGroupID,
   638 	}
   677 	}
   639 	c.AddCommand(completionCmd)
   678 	c.AddCommand(completionCmd)
   640 
   679 
   641 	out := c.OutOrStdout()
   680 	out := c.OutOrStdout()
   642 	noDesc := c.CompletionOptions.DisableDescriptions
   681 	noDesc := c.CompletionOptions.DisableDescriptions