// Copyright 2013-2023 The Cobra Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cobra

import (
	
	
	
	
	
	

	
)

const (
	// ShellCompRequestCmd is the name of the hidden command that is used to request
	// completion results from the program.  It is used by the shell completion scripts.
	ShellCompRequestCmd = "__complete"
	// ShellCompNoDescRequestCmd is the name of the hidden command that is used to request
	// completion results without their description.  It is used by the shell completion scripts.
	ShellCompNoDescRequestCmd = "__completeNoDesc"
)

// Global map of flag completion functions. Make sure to use flagCompletionMutex before you try to read and write from it.
var flagCompletionFunctions = map[*pflag.Flag]func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective){}

// lock for reading and writing from flagCompletionFunctions
var flagCompletionMutex = &sync.RWMutex{}

// ShellCompDirective is a bit map representing the different behaviors the shell
// can be instructed to have once completions have been provided.
type ShellCompDirective int

type flagCompError struct {
	subCommand string
	flagName   string
}

func ( *flagCompError) () string {
	return "Subcommand '" + .subCommand + "' does not support flag '" + .flagName + "'"
}

const (
	// ShellCompDirectiveError indicates an error occurred and completions should be ignored.
	ShellCompDirectiveError ShellCompDirective = 1 << iota

	// ShellCompDirectiveNoSpace indicates that the shell should not add a space
	// after the completion even if there is a single completion provided.
	ShellCompDirectiveNoSpace

	// ShellCompDirectiveNoFileComp indicates that the shell should not provide
	// file completion even when no completion is provided.
	ShellCompDirectiveNoFileComp

	// ShellCompDirectiveFilterFileExt indicates that the provided completions
	// should be used as file extension filters.
	// For flags, using Command.MarkFlagFilename() and Command.MarkPersistentFlagFilename()
	// is a shortcut to using this directive explicitly.  The BashCompFilenameExt
	// annotation can also be used to obtain the same behavior for flags.
	ShellCompDirectiveFilterFileExt

	// ShellCompDirectiveFilterDirs indicates that only directory names should
	// be provided in file completion.  To request directory names within another
	// directory, the returned completions should specify the directory within
	// which to search.  The BashCompSubdirsInDir annotation can be used to
	// obtain the same behavior but only for flags.
	ShellCompDirectiveFilterDirs

	// ShellCompDirectiveKeepOrder indicates that the shell should preserve the order
	// in which the completions are provided
	ShellCompDirectiveKeepOrder

	// ===========================================================================

	// All directives using iota should be above this one.
	// For internal use.
	shellCompDirectiveMaxValue

	// ShellCompDirectiveDefault indicates to let the shell perform its default
	// behavior after completions have been provided.
	// This one must be last to avoid messing up the iota count.
	ShellCompDirectiveDefault ShellCompDirective = 0
)

const (
	// Constants for the completion command
	compCmdName              = "completion"
	compCmdNoDescFlagName    = "no-descriptions"
	compCmdNoDescFlagDesc    = "disable completion descriptions"
	compCmdNoDescFlagDefault = false
)

// CompletionOptions are the options to control shell completion
type CompletionOptions struct {
	// DisableDefaultCmd prevents Cobra from creating a default 'completion' command
	DisableDefaultCmd bool
	// DisableNoDescFlag prevents Cobra from creating the '--no-descriptions' flag
	// for shells that support completion descriptions
	DisableNoDescFlag bool
	// DisableDescriptions turns off all completion descriptions for shells
	// that support them
	DisableDescriptions bool
	// HiddenDefaultCmd makes the default 'completion' command hidden
	HiddenDefaultCmd bool
}

// NoFileCompletions can be used to disable file completion for commands that should
// not trigger file completions.
func ( *Command,  []string,  string) ([]string, ShellCompDirective) {
	return nil, ShellCompDirectiveNoFileComp
}

// FixedCompletions can be used to create a completion function which always
// returns the same results.
func ( []string,  ShellCompDirective) func( *Command,  []string,  string) ([]string, ShellCompDirective) {
	return func( *Command,  []string,  string) ([]string, ShellCompDirective) {
		return , 
	}
}

// RegisterFlagCompletionFunc should be called to register a function to provide completion for a flag.
func ( *Command) ( string,  func( *Command,  []string,  string) ([]string, ShellCompDirective)) error {
	 := .Flag()
	if  == nil {
		return fmt.Errorf("RegisterFlagCompletionFunc: flag '%s' does not exist", )
	}
	flagCompletionMutex.Lock()
	defer flagCompletionMutex.Unlock()

	if ,  := flagCompletionFunctions[];  {
		return fmt.Errorf("RegisterFlagCompletionFunc: flag '%s' already registered", )
	}
	flagCompletionFunctions[] = 
	return nil
}

// GetFlagCompletionFunc returns the completion function for the given flag of the command, if available.
func ( *Command) ( string) (func(*Command, []string, string) ([]string, ShellCompDirective), bool) {
	 := .Flag()
	if  == nil {
		return nil, false
	}

	flagCompletionMutex.RLock()
	defer flagCompletionMutex.RUnlock()

	,  := flagCompletionFunctions[]
	return , 
}

// Returns a string listing the different directive enabled in the specified parameter
func ( ShellCompDirective) () string {
	var  []string
	if &ShellCompDirectiveError != 0 {
		 = append(, "ShellCompDirectiveError")
	}
	if &ShellCompDirectiveNoSpace != 0 {
		 = append(, "ShellCompDirectiveNoSpace")
	}
	if &ShellCompDirectiveNoFileComp != 0 {
		 = append(, "ShellCompDirectiveNoFileComp")
	}
	if &ShellCompDirectiveFilterFileExt != 0 {
		 = append(, "ShellCompDirectiveFilterFileExt")
	}
	if &ShellCompDirectiveFilterDirs != 0 {
		 = append(, "ShellCompDirectiveFilterDirs")
	}
	if &ShellCompDirectiveKeepOrder != 0 {
		 = append(, "ShellCompDirectiveKeepOrder")
	}
	if len() == 0 {
		 = append(, "ShellCompDirectiveDefault")
	}

	if  >= shellCompDirectiveMaxValue {
		return fmt.Sprintf("ERROR: unexpected ShellCompDirective value: %d", )
	}
	return strings.Join(, ", ")
}

// initCompleteCmd adds a special hidden command that can be used to request custom completions.
func ( *Command) ( []string) {
	 := &Command{
		Use:                   fmt.Sprintf("%s [command-line]", ShellCompRequestCmd),
		Aliases:               []string{ShellCompNoDescRequestCmd},
		DisableFlagsInUseLine: true,
		Hidden:                true,
		DisableFlagParsing:    true,
		Args:                  MinimumNArgs(1),
		Short:                 "Request shell completion choices for the specified command-line",
		Long: fmt.Sprintf("%[2]s is a special command that is used by the shell completion logic\n%[1]s",
			"to request completion choices for the specified command-line.", ShellCompRequestCmd),
		Run: func( *Command,  []string) {
			, , ,  := .getCompletions()
			if  != nil {
				CompErrorln(.Error())
				// Keep going for multiple reasons:
				// 1- There could be some valid completions even though there was an error
				// 2- Even without completions, we need to print the directive
			}

			 := .CalledAs() == ShellCompNoDescRequestCmd
			if ! {
				if ,  := strconv.ParseBool(getEnvConfig(, configEnvVarSuffixDescriptions));  == nil {
					 = !
				}
			}
			 := GetActiveHelpConfig() == activeHelpGlobalDisable
			 := .OutOrStdout()
			for ,  := range  {
				if  && strings.HasPrefix(, activeHelpMarker) {
					// Remove all activeHelp entries if it's disabled.
					continue
				}
				if  {
					// Remove any description that may be included following a tab character.
					 = strings.SplitN(, "\t", 2)[0]
				}

				// Make sure we only write the first line to the output.
				// This is needed if a description contains a linebreak.
				// Otherwise the shell scripts will interpret the other lines as new flags
				// and could therefore provide a wrong completion.
				 = strings.SplitN(, "\n", 2)[0]

				// Finally trim the completion.  This is especially important to get rid
				// of a trailing tab when there are no description following it.
				// For example, a sub-command without a description should not be completed
				// with a tab at the end (or else zsh will show a -- following it
				// although there is no description).
				 = strings.TrimSpace()

				// Print each possible completion to the output for the completion script to consume.
				fmt.Fprintln(, )
			}

			// As the last printout, print the completion directive for the completion script to parse.
			// The directive integer must be that last character following a single colon (:).
			// The completion script expects :<directive>
			fmt.Fprintf(, ":%d\n", )

			// Print some helpful info to stderr for the user to understand.
			// Output from stderr must be ignored by the completion script.
			fmt.Fprintf(.ErrOrStderr(), "Completion ended with directive: %s\n", .string())
		},
	}
	.AddCommand()
	, ,  := .Find()
	if  != nil || .Name() != ShellCompRequestCmd {
		// Only create this special command if it is actually being called.
		// This reduces possible side-effects of creating such a command;
		// for example, having this command would cause problems to a
		// cobra program that only consists of the root command, since this
		// command would cause the root command to suddenly have a subcommand.
		.RemoveCommand()
	}
}

func ( *Command) ( []string) (*Command, []string, ShellCompDirective, error) {
	// The last argument, which is not completely typed by the user,
	// should not be part of the list of arguments
	 := [len()-1]
	 := [:len()-1]

	var  *Command
	var  []string
	var  error
	// Find the real command for which completion must be performed
	// check if we need to traverse here to parse local flags on parent commands
	if .Root().TraverseChildren {
		, ,  = .Root().Traverse()
	} else {
		// For Root commands that don't specify any value for their Args fields, when we call
		// Find(), if those Root commands don't have any sub-commands, they will accept arguments.
		// However, because we have added the __complete sub-command in the current code path, the
		// call to Find() -> legacyArgs() will return an error if there are any arguments.
		// To avoid this, we first remove the __complete command to get back to having no sub-commands.
		 := .Root()
		if len(.Commands()) == 1 {
			.RemoveCommand()
		}

		, ,  = .Find()
	}
	if  != nil {
		// Unable to find the real command. E.g., <program> someInvalidCmd <TAB>
		return , []string{}, ShellCompDirectiveDefault, fmt.Errorf("unable to find a command for arguments: %v", )
	}
	.ctx = .ctx

	// These flags are normally added when `execute()` is called on `finalCmd`,
	// however, when doing completion, we don't call `finalCmd.execute()`.
	// Let's add the --help and --version flag ourselves but only if the finalCmd
	// has not disabled flag parsing; if flag parsing is disabled, it is up to the
	// finalCmd itself to handle the completion of *all* flags.
	if !.DisableFlagParsing {
		.InitDefaultHelpFlag()
		.InitDefaultVersionFlag()
	}

	// Check if we are doing flag value completion before parsing the flags.
	// This is important because if we are completing a flag value, we need to also
	// remove the flag name argument from the list of finalArgs or else the parsing
	// could fail due to an invalid value (incomplete) for the flag.
	, , ,  := checkIfFlagCompletion(, , )

	// Check if interspersed is false or -- was set on a previous arg.
	// This works by counting the arguments. Normally -- is not counted as arg but
	// if -- was already set or interspersed is false and there is already one arg then
	// the extra added -- is counted as arg.
	 := true
	_ = .ParseFlags(append(, "--"))
	 := .Flags().NArg()

	// Parse the flags early so we can check if required flags are set
	if  = .ParseFlags();  != nil {
		return , []string{}, ShellCompDirectiveDefault, fmt.Errorf("Error while parsing flags from args %v: %s", , .Error())
	}

	 := .Flags().NArg()
	if  >  {
		// don't do flag completion (see above)
		 = false
	}
	// Error while attempting to parse flags
	if  != nil {
		// If error type is flagCompError and we don't want flagCompletion we should ignore the error
		if ,  := .(*flagCompError); !( && !) {
			return , []string{}, ShellCompDirectiveDefault, 
		}
	}

	// Look for the --help or --version flags.  If they are present,
	// there should be no further completions.
	if helpOrVersionFlagPresent() {
		return , []string{}, ShellCompDirectiveNoFileComp, nil
	}

	// We only remove the flags from the arguments if DisableFlagParsing is not set.
	// This is important for commands which have requested to do their own flag completion.
	if !.DisableFlagParsing {
		 = .Flags().Args()
	}

	if  != nil &&  {
		// Check if we are completing a flag value subject to annotations
		if ,  := .Annotations[BashCompFilenameExt];  {
			if len() != 0 {
				// File completion filtered by extensions
				return , , ShellCompDirectiveFilterFileExt, nil
			}

			// The annotation requests simple file completion.  There is no reason to do
			// that since it is the default behavior anyway.  Let's ignore this annotation
			// in case the program also registered a completion function for this flag.
			// Even though it is a mistake on the program's side, let's be nice when we can.
		}

		if ,  := .Annotations[BashCompSubdirsInDir];  {
			if len() == 1 {
				// Directory completion from within a directory
				return , , ShellCompDirectiveFilterDirs, nil
			}
			// Directory completion
			return , []string{}, ShellCompDirectiveFilterDirs, nil
		}
	}

	var  []string
	var  ShellCompDirective

	// Enforce flag groups before doing flag completions
	.enforceFlagGroupsForCompletion()

	// Note that we want to perform flagname completion even if finalCmd.DisableFlagParsing==true;
	// doing this allows for completion of persistent flag names even for commands that disable flag parsing.
	//
	// When doing completion of a flag name, as soon as an argument starts with
	// a '-' we know it is a flag.  We cannot use isFlagArg() here as it requires
	// the flag name to be complete
	if  == nil && len() > 0 && [0] == '-' && !strings.Contains(, "=") &&  {
		// First check for required flags
		 = completeRequireFlags(, )

		// If we have not found any required flags, only then can we show regular flags
		if len() == 0 {
			 := func( *pflag.Flag) {
				if !.Changed ||
					strings.Contains(.Value.Type(), "Slice") ||
					strings.Contains(.Value.Type(), "Array") {
					// If the flag is not already present, or if it can be specified multiple times (Array or Slice)
					// we suggest it as a completion
					 = append(, getFlagNameCompletions(, )...)
				}
			}

			// We cannot use finalCmd.Flags() because we may not have called ParsedFlags() for commands
			// that have set DisableFlagParsing; it is ParseFlags() that merges the inherited and
			// non-inherited flags.
			.InheritedFlags().VisitAll(func( *pflag.Flag) {
				()
			})
			// Try to complete non-inherited flags even if DisableFlagParsing==true.
			// This allows programs to tell Cobra about flags for completion even
			// if the actual parsing of flags is not done by Cobra.
			// For instance, Helm uses this to provide flag name completion for
			// some of its plugins.
			.NonInheritedFlags().VisitAll(func( *pflag.Flag) {
				()
			})
		}

		 = ShellCompDirectiveNoFileComp
		if len() == 1 && strings.HasSuffix([0], "=") {
			// If there is a single completion, the shell usually adds a space
			// after the completion.  We don't want that if the flag ends with an =
			 = ShellCompDirectiveNoSpace
		}

		if !.DisableFlagParsing {
			// If DisableFlagParsing==false, we have completed the flags as known by Cobra;
			// we can return what we found.
			// If DisableFlagParsing==true, Cobra may not be aware of all flags, so we
			// let the logic continue to see if ValidArgsFunction needs to be called.
			return , , , nil
		}
	} else {
		 = ShellCompDirectiveDefault
		if  == nil {
			 := false
			// If TraverseChildren is true on the root command we don't check for
			// local flags because we can use a local flag on a parent command
			if !.Root().TraverseChildren {
				// Check if there are any local, non-persistent flags on the command-line
				 := .LocalNonPersistentFlags()
				.NonInheritedFlags().VisitAll(func( *pflag.Flag) {
					if .Lookup(.Name) != nil && .Changed {
						 = true
					}
				})
			}

			// Complete subcommand names, including the help command
			if len() == 0 && ! {
				// We only complete sub-commands if:
				// - there are no arguments on the command-line and
				// - there are no local, non-persistent flags on the command-line or TraverseChildren is true
				for ,  := range .Commands() {
					if .IsAvailableCommand() ||  == .helpCommand {
						if strings.HasPrefix(.Name(), ) {
							 = append(, fmt.Sprintf("%s\t%s", .Name(), .Short))
						}
						 = ShellCompDirectiveNoFileComp
					}
				}
			}

			// Complete required flags even without the '-' prefix
			 = append(, completeRequireFlags(, )...)

			// Always complete ValidArgs, even if we are completing a subcommand name.
			// This is for commands that have both subcommands and ValidArgs.
			if len(.ValidArgs) > 0 {
				if len() == 0 {
					// ValidArgs are only for the first argument
					for ,  := range .ValidArgs {
						if strings.HasPrefix(, ) {
							 = append(, )
						}
					}
					 = ShellCompDirectiveNoFileComp

					// If no completions were found within commands or ValidArgs,
					// see if there are any ArgAliases that should be completed.
					if len() == 0 {
						for ,  := range .ArgAliases {
							if strings.HasPrefix(, ) {
								 = append(, )
							}
						}
					}
				}

				// If there are ValidArgs specified (even if they don't match), we stop completion.
				// Only one of ValidArgs or ValidArgsFunction can be used for a single command.
				return , , , nil
			}

			// Let the logic continue so as to add any ValidArgsFunction completions,
			// even if we already found sub-commands.
			// This is for commands that have subcommands but also specify a ValidArgsFunction.
		}
	}

	// Find the completion function for the flag or command
	var  func( *Command,  []string,  string) ([]string, ShellCompDirective)
	if  != nil &&  {
		flagCompletionMutex.RLock()
		 = flagCompletionFunctions[]
		flagCompletionMutex.RUnlock()
	} else {
		 = .ValidArgsFunction
	}
	if  != nil {
		// Go custom completion defined for this flag or command.
		// Call the registered completion function to get the completions.
		var  []string
		,  = (, , )
		 = append(, ...)
	}

	return , , , nil
}

func helpOrVersionFlagPresent( *Command) bool {
	if  := .Flags().Lookup("version");  != nil &&
		len(.Annotations[FlagSetByCobraAnnotation]) > 0 && .Changed {
		return true
	}
	if  := .Flags().Lookup("help");  != nil &&
		len(.Annotations[FlagSetByCobraAnnotation]) > 0 && .Changed {
		return true
	}
	return false
}

func getFlagNameCompletions( *pflag.Flag,  string) []string {
	if nonCompletableFlag() {
		return []string{}
	}

	var  []string
	 := "--" + .Name
	if strings.HasPrefix(, ) {
		// Flag without the =
		 = append(, fmt.Sprintf("%s\t%s", , .Usage))

		// Why suggest both long forms: --flag and --flag= ?
		// This forces the user to *always* have to type either an = or a space after the flag name.
		// Let's be nice and avoid making users have to do that.
		// Since boolean flags and shortname flags don't show the = form, let's go that route and never show it.
		// The = form will still work, we just won't suggest it.
		// This also makes the list of suggested flags shorter as we avoid all the = forms.
		//
		// if len(flag.NoOptDefVal) == 0 {
		// 	// Flag requires a value, so it can be suffixed with =
		// 	flagName += "="
		// 	completions = append(completions, fmt.Sprintf("%s\t%s", flagName, flag.Usage))
		// }
	}

	 = "-" + .Shorthand
	if len(.Shorthand) > 0 && strings.HasPrefix(, ) {
		 = append(, fmt.Sprintf("%s\t%s", , .Usage))
	}

	return 
}

func completeRequireFlags( *Command,  string) []string {
	var  []string

	 := func( *pflag.Flag) {
		if ,  := .Annotations[BashCompOneRequiredFlag];  {
			if !.Changed {
				// If the flag is not already present, we suggest it as a completion
				 = append(, getFlagNameCompletions(, )...)
			}
		}
	}

	// We cannot use finalCmd.Flags() because we may not have called ParsedFlags() for commands
	// that have set DisableFlagParsing; it is ParseFlags() that merges the inherited and
	// non-inherited flags.
	.InheritedFlags().VisitAll(func( *pflag.Flag) {
		()
	})
	.NonInheritedFlags().VisitAll(func( *pflag.Flag) {
		()
	})

	return 
}

func checkIfFlagCompletion( *Command,  []string,  string) (*pflag.Flag, []string, string, error) {
	if .DisableFlagParsing {
		// We only do flag completion if we are allowed to parse flags
		// This is important for commands which have requested to do their own flag completion.
		return nil, , , nil
	}

	var  string
	 := 
	 := false
	 := 

	// When doing completion of a flag name, as soon as an argument starts with
	// a '-' we know it is a flag.  We cannot use isFlagArg() here as that function
	// requires the flag name to be complete
	if len() > 0 && [0] == '-' {
		if  := strings.Index(, "=");  >= 0 {
			// Flag with an =
			if strings.HasPrefix([:], "--") {
				// Flag has full name
				 = [2:]
			} else {
				// Flag is shorthand
				// We have to get the last shorthand flag name
				// e.g. `-asd` => d to provide the correct completion
				// https://github.com/spf13/cobra/issues/1257
				 = [-1 : ]
			}
			 = [+1:]
			 = true
		} else {
			// Normal flag completion
			return nil, , , nil
		}
	}

	if len() == 0 {
		if len() > 0 {
			 := [len()-1]
			if isFlagArg() {
				// Only consider the case where the flag does not contain an =.
				// If the flag contains an = it means it has already been fully processed,
				// so we don't need to deal with it here.
				if  := strings.Index(, "=");  < 0 {
					if strings.HasPrefix(, "--") {
						// Flag has full name
						 = [2:]
					} else {
						// Flag is shorthand
						// We have to get the last shorthand flag name
						// e.g. `-asd` => d to provide the correct completion
						// https://github.com/spf13/cobra/issues/1257
						 = [len()-1:]
					}
					// Remove the uncompleted flag or else there could be an error created
					// for an invalid value for that flag
					 = [:len()-1]
				}
			}
		}
	}

	if len() == 0 {
		// Not doing flag completion
		return nil, , , nil
	}

	 := findFlag(, )
	if  == nil {
		// Flag not supported by this command, the interspersed option might be set so return the original args
		return nil, , , &flagCompError{subCommand: .Name(), flagName: }
	}

	if ! {
		if len(.NoOptDefVal) != 0 {
			// We had assumed dealing with a two-word flag but the flag is a boolean flag.
			// In that case, there is no value following it, so we are not really doing flag completion.
			// Reset everything to do noun completion.
			 = 
			 = nil
		}
	}

	return , , , nil
}

// InitDefaultCompletionCmd adds a default 'completion' command to c.
// This function will do nothing if any of the following is true:
// 1- the feature has been explicitly disabled by the program,
// 2- c has no subcommands (to avoid creating one),
// 3- c already has a 'completion' command provided by the program.
func ( *Command) () {
	if .CompletionOptions.DisableDefaultCmd || !.HasSubCommands() {
		return
	}

	for ,  := range .commands {
		if .Name() == compCmdName || .HasAlias(compCmdName) {
			// A completion command is already available
			return
		}
	}

	 := !.CompletionOptions.DisableNoDescFlag && !.CompletionOptions.DisableDescriptions

	 := &Command{
		Use:   compCmdName,
		Short: "Generate the autocompletion script for the specified shell",
		Long: fmt.Sprintf(`Generate the autocompletion script for %[1]s for the specified shell.
See each sub-command's help for details on how to use the generated script.
`, .Root().Name()),
		Args:              NoArgs,
		ValidArgsFunction: NoFileCompletions,
		Hidden:            .CompletionOptions.HiddenDefaultCmd,
		GroupID:           .completionCommandGroupID,
	}
	.AddCommand()

	 := .OutOrStdout()
	 := .CompletionOptions.DisableDescriptions
	 := "Generate the autocompletion script for %s"
	 := &Command{
		Use:   "bash",
		Short: fmt.Sprintf(, "bash"),
		Long: fmt.Sprintf(`Generate the autocompletion script for the bash shell.

This script depends on the 'bash-completion' package.
If it is not installed already, you can install it via your OS's package manager.

To load completions in your current shell session:

	source <(%[1]s completion bash)

To load completions for every new session, execute once:

#### Linux:

	%[1]s completion bash > /etc/bash_completion.d/%[1]s

#### macOS:

	%[1]s completion bash > $(brew --prefix)/etc/bash_completion.d/%[1]s

You will need to start a new shell for this setup to take effect.
`, .Root().Name()),
		Args:                  NoArgs,
		DisableFlagsInUseLine: true,
		ValidArgsFunction:     NoFileCompletions,
		RunE: func( *Command,  []string) error {
			return .Root().GenBashCompletionV2(, !)
		},
	}
	if  {
		.Flags().BoolVar(&, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)
	}

	 := &Command{
		Use:   "zsh",
		Short: fmt.Sprintf(, "zsh"),
		Long: fmt.Sprintf(`Generate the autocompletion script for the zsh shell.

If shell completion is not already enabled in your environment you will need
to enable it.  You can execute the following once:

	echo "autoload -U compinit; compinit" >> ~/.zshrc

To load completions in your current shell session:

	source <(%[1]s completion zsh)

To load completions for every new session, execute once:

#### Linux:

	%[1]s completion zsh > "${fpath[1]}/_%[1]s"

#### macOS:

	%[1]s completion zsh > $(brew --prefix)/share/zsh/site-functions/_%[1]s

You will need to start a new shell for this setup to take effect.
`, .Root().Name()),
		Args:              NoArgs,
		ValidArgsFunction: NoFileCompletions,
		RunE: func( *Command,  []string) error {
			if  {
				return .Root().GenZshCompletionNoDesc()
			}
			return .Root().GenZshCompletion()
		},
	}
	if  {
		.Flags().BoolVar(&, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)
	}

	 := &Command{
		Use:   "fish",
		Short: fmt.Sprintf(, "fish"),
		Long: fmt.Sprintf(`Generate the autocompletion script for the fish shell.

To load completions in your current shell session:

	%[1]s completion fish | source

To load completions for every new session, execute once:

	%[1]s completion fish > ~/.config/fish/completions/%[1]s.fish

You will need to start a new shell for this setup to take effect.
`, .Root().Name()),
		Args:              NoArgs,
		ValidArgsFunction: NoFileCompletions,
		RunE: func( *Command,  []string) error {
			return .Root().GenFishCompletion(, !)
		},
	}
	if  {
		.Flags().BoolVar(&, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)
	}

	 := &Command{
		Use:   "powershell",
		Short: fmt.Sprintf(, "powershell"),
		Long: fmt.Sprintf(`Generate the autocompletion script for powershell.

To load completions in your current shell session:

	%[1]s completion powershell | Out-String | Invoke-Expression

To load completions for every new session, add the output of the above command
to your powershell profile.
`, .Root().Name()),
		Args:              NoArgs,
		ValidArgsFunction: NoFileCompletions,
		RunE: func( *Command,  []string) error {
			if  {
				return .Root().GenPowerShellCompletion()
			}
			return .Root().GenPowerShellCompletionWithDesc()

		},
	}
	if  {
		.Flags().BoolVar(&, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)
	}

	.AddCommand(, , , )
}

func findFlag( *Command,  string) *pflag.Flag {
	 := .Flags()
	if len() == 1 {
		// First convert the short flag into a long flag
		// as the cmd.Flag() search only accepts long flags
		if  := .ShorthandLookup();  != nil {
			 = .Name
		} else {
			 := .InheritedFlags()
			if  = .ShorthandLookup();  != nil {
				 = .Name
			} else {
				return nil
			}
		}
	}
	return .Flag()
}

// CompDebug prints the specified string to the same file as where the
// completion script prints its logs.
// Note that completion printouts should never be on stdout as they would
// be wrongly interpreted as actual completion choices by the completion script.
func ( string,  bool) {
	 = fmt.Sprintf("[Debug] %s", )

	// Such logs are only printed when the user has set the environment
	// variable BASH_COMP_DEBUG_FILE to the path of some file to be used.
	if  := os.Getenv("BASH_COMP_DEBUG_FILE");  != "" {
		,  := os.OpenFile(,
			os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
		if  == nil {
			defer .Close()
			WriteStringAndCheck(, )
		}
	}

	if  {
		// Must print to stderr for this not to be read by the completion script.
		fmt.Fprint(os.Stderr, )
	}
}

// CompDebugln prints the specified string with a newline at the end
// to the same file as where the completion script prints its logs.
// Such logs are only printed when the user has set the environment
// variable BASH_COMP_DEBUG_FILE to the path of some file to be used.
func ( string,  bool) {
	CompDebug(fmt.Sprintf("%s\n", ), )
}

// CompError prints the specified completion message to stderr.
func ( string) {
	 = fmt.Sprintf("[Error] %s", )
	CompDebug(, true)
}

// CompErrorln prints the specified completion message to stderr with a newline at the end.
func ( string) {
	CompError(fmt.Sprintf("%s\n", ))
}

// These values should not be changed: users will be using them explicitly.
const (
	configEnvVarGlobalPrefix       = "COBRA"
	configEnvVarSuffixDescriptions = "COMPLETION_DESCRIPTIONS"
)

var configEnvVarPrefixSubstRegexp = regexp.MustCompile(`[^A-Z0-9_]`)

// configEnvVar returns the name of the program-specific configuration environment
// variable.  It has the format <PROGRAM>_<SUFFIX> where <PROGRAM> is the name of the
// root command in upper case, with all non-ASCII-alphanumeric characters replaced by `_`.
func configEnvVar(,  string) string {
	// This format should not be changed: users will be using it explicitly.
	 := strings.ToUpper(fmt.Sprintf("%s_%s", , ))
	 = configEnvVarPrefixSubstRegexp.ReplaceAllString(, "_")
	return 
}

// getEnvConfig returns the value of the configuration environment variable
// <PROGRAM>_<SUFFIX> where <PROGRAM> is the name of the root command in upper
// case, with all non-ASCII-alphanumeric characters replaced by `_`.
// If the value is empty or not set, the value of the environment variable
// COBRA_<SUFFIX> is returned instead.
func getEnvConfig( *Command,  string) string {
	 := os.Getenv(configEnvVar(.Root().Name(), ))
	if  == "" {
		 = os.Getenv(configEnvVar(configEnvVarGlobalPrefix, ))
	}
	return 
}