Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix multiple fish completion issues #1249

Merged
merged 4 commits into from
May 3, 2021

Conversation

marckhouzam
Copy link
Collaborator

@marckhouzam marckhouzam commented Oct 7, 2020

Fixes #1248
Fixes #1303
Fixes #1214
Fixes #1306

This PR fixes multiple bugs in the fish completion script.

Please ses each issue for details.

@marckhouzam
Copy link
Collaborator Author

Here is how to test this specific fix. An extensive test program is included at the bottom.

Test 1 - ShellCompDirectiveNoSpace not respected
Before the PR:

$ fish
$ ./testprog completion fish | source

$ ./testprog nospace compo<TAB>
# and
$ ./testprog --nospace compo<TAB>

will complete to:

$ ./testprog nospace compost<SPACE>
# and
$ ./testprog --nospace compost<SPACE>

the <SPACE> is wrong at the end of the completion because ValidArgsFunction requested ShellCompDirectiveNoSpace, as can be seen by:

$ ./testprog __complete nospace compo
complete	description1
compost	description2
:2
Completion ended with directive: ShellCompDirectiveNoSpace

Testing with this PR in the exact same way will not output the <SPACE> after the word compost.

Test 2 - ShellCompDirectiveNoSpace not properly handling descriptions

The nospace logic for fish does not handle the case when there is a description. To achieve "nospace" the script adds a second completion with an extra "." to prevent the shell from adding a space. However if there is a description, the extra "." is added to the description instead of the completion, and the nospace directive does not work.

Before the PR:

$ fish
$ ./testprog completion fish | source

$ ./testprog nospace first compo<TAB>

will complete to:

$ ./testprog nospace first compo<SPACE>

the <SPACE> is wrong at the end of the completion because ValidArgsFunction requested ShellCompDirectiveNoSpace, as can be seen by:

$ ./testprog __complete nospace compo
compost	description2
:2
Completion ended with directive: ShellCompDirectiveNoSpace

Notice this is slightly different than the previous case because a single completion is returned by the __complete command, but the <SPACE> is still added, this time because of the description.

Testing with this PR in the exact same way will not output the <SPACE> after the word compost.

Test 3 - File completion not always done when requested

Before the PR:

$ fish
$ ./testprog completion fish | source
$ touch myfile

$ ./testprog withfile myfi<TAB>

will not perform file completion and will not show myfile although it should have.

Testing with this PR in the exact same way will trigger file completion and will show myfile as expected.

Extensive test program to execute the above tests, but also any regression tests:

package main

import (
	"fmt"
	"os"
	"strings"

	"github.com/spf13/cobra"
)

var completionNoDesc bool

var completionCmd = &cobra.Command{
	Use:   "completion [bashzsh|fish|powershell]",
	Short: "Generate completion script",
	Long: `To load completions:

Bash:

$ source <(testprog completion bash)

# To load completions for each session, execute once:
Linux:
  $ testprog completion bash > /etc/bash_completion.d/testprog
MacOS:
  $ testprog completion bash > /usr/local/etc/bash_completion.d/testprog

Zsh:

$ source <(testprog completion zsh)
$ compdef _testprog testprog

# To load completions for each session, execute once:
$ testprog completion zsh > "${fpath[1]}/_testprog"

Fish:

$ testprog completion fish | source

# To load completions for each session, execute once:
$ testprog completion fish > ~/.config/fish/completions/testprog.fish

PowerShell:

PS C:\> testprog completion powershell | Out-String | Invoke-Expression

To load completions for every new session, add the output of the above command
to your powershell profile.
`,
	DisableFlagsInUseLine: true,
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return []string{"bash\tBash completion", "zsh", "fish", "powershell"}, cobra.ShellCompDirectiveNoFileComp
	},
	Args: cobra.ExactValidArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		switch args[0] {
		case "bash":
			cmd.Root().GenBashCompletion(os.Stdout)
		case "zsh":
			if !completionNoDesc {
				cmd.Root().GenZshCompletion(os.Stdout)
			} else {
				cmd.Root().GenZshCompletionNoDesc(os.Stdout)
			}
		case "fish":
			cmd.Root().GenFishCompletion(os.Stdout, !completionNoDesc)
		case "powershell":
			cmd.Root().GenPowerShellCompletion(os.Stdout)
		}
	},
}

var rootCmd = &cobra.Command{
	Use: "testprog",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("rootCmd called")
	},
}

var vargsCmd = &cobra.Command{
	Use:        "vargs",
	Short:      "Cmd with ValidArgs AND a subcmd",
	ValidArgs:  []string{"one", "two", "three"},
	ArgAliases: []string{"un", "deux", "trois"},
	Args:       cobra.MinimumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("vargsCmd called")
	},
}

var childVargsCmd = &cobra.Command{
	Use:   "childVargs",
	Short: "Child command",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("childVargs called")
	},
}

var aliasCmd = &cobra.Command{
	Use:     "cmdWithAlias",
	Short:   "Command with aliases",
	Aliases: []string{"aliasCmd", "cmdAlias"},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("cmdWithAlias called")
	},
}

// A command with no short description
var nodescriptionCmd = &cobra.Command{
	Use: "nodesc",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("nodesc called")
	},
}

// File filtering for the first argument
// Replaces MarkZshCompPositionalArgumentFile(1, string{"*.log", "*.txt"})
var filterFileCmd = &cobra.Command{
	Use:   "filterFile",
	Short: "Only list file of type [*.log,*.txt]",
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		if len(args) == 0 {
			return []string{"log", "txt"}, cobra.ShellCompDirectiveFilterFileExt
		}
		// No more expected arguments, so turn off file completion
		return nil, cobra.ShellCompDirectiveNoFileComp
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("filterFile called")
	},
}

// Turn off file completion for all arguments
var noFileCmd = &cobra.Command{
	Use:   "nofile",
	Short: "No file completion done",
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return nil, cobra.ShellCompDirectiveNoFileComp
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("nofile called")
	},
}

// Full file completion for arguments
var fullFileCmd = &cobra.Command{
	Use:   "fullFile [filename]",
	Short: "Full file completion",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("fullFile called")
	},
}

// Only allow directory name completion and only for the first argument
var dirOnlyCmd = &cobra.Command{
	Use:   "dirOnly [dirname]",
	Short: "Only list directories in completion",
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		if len(args) == 0 {
			return nil, cobra.ShellCompDirectiveFilterDirs
		}
		// No more expected arguments, so turn off file completion
		return nil, cobra.ShellCompDirectiveNoFileComp
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("dirOnly called")
	},
}

// Only allow directory name from within a specified directory and only for the first argument
var subdirCmd = &cobra.Command{
	Use:   "subdir [sub-dirname]",
	Short: "Only list directories within themes/",
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		if len(args) == 0 {
			return []string{"themes"}, cobra.ShellCompDirectiveFilterDirs | cobra.ShellCompDirectiveNoFileComp
		}
		// No more expected arguments, so turn off file completion
		return nil, cobra.ShellCompDirectiveNoFileComp
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("subdir called")
	},
}

// Test file completion when returning other completions
var compAndFileCmd = &cobra.Command{
	Use:   "compAndFile [sun|moon|<filename>]",
	Short: "Provide some completions and file completion when prefix does not match",
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		if len(args) != 0 {
			return []string{"nginx", "thanos"}, cobra.ShellCompDirectiveNoFileComp
		}
		var completions []string
		for _, comp := range []string{"install", "uninstall"} {
			completions = append(completions, comp)
		}
		return completions, cobra.ShellCompDirectiveDefault
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("compAndFile called")
	},
}

var colonCmd = &cobra.Command{
	Use:       "cmdColonArgs",
	Short:     "Command with colon args",
	ValidArgs: []string{"first:ONE", "first:SECOND"},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("colonCmd called")
	},
}

var longDescCmd = &cobra.Command{
	Use:       "cmdLongDesc12345678901234567890123456789012345678901234567890",
	Short:     `We have here a quite long description which should go over the length of the shell width.  What should we do with such a long description? zsh and fish handle it nicely, so we should prepare bash to handle it in the same fashion`,
	ValidArgs: []string{"first:ONE", "first:SECOND"},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("colonCmd called")
	},
}

var specialCharDescCmd = &cobra.Command{
	Use:   "specialChar",
	Short: "Description contains chars like ` and maybe others",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("specialChar cmd called")
	},
}

var noSpaceCmd = &cobra.Command{
	Use:   "nospace",
	Short: "followed by completion with noSpace, even for file completion",
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		comps := []string{"complete\tdescription1", "compost\tdescription2"}
		if len(args) == 0 {
			// Allow file completion with ShellCompDirectiveNoSpace
			return comps, cobra.ShellCompDirectiveNoSpace
		}

		var finalComps []string
		for _, comp := range comps {
			if strings.HasPrefix(comp, toComplete) {
				finalComps = append(finalComps, comp)
			}
		}
		return finalComps, cobra.ShellCompDirectiveNoSpace
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("nospace cmd called")
	},
}

var sentenceCmd = &cobra.Command{
	Use:   "sentence",
	Short: "completion has spaces",
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		// Allow file completion with ShellCompDirectiveNoSpace
		return []string{"comp is a sentence\tFirst comp", "and another sentence\tsecondComp"}, cobra.ShellCompDirectiveNoFileComp
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("sentence cmd called")
	},
}

var withfileCmd = &cobra.Command{
	Use:   "withfile",
	Short: "completion always returned and has file completion",
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		// We do not consider the toComplete prefix and always return a completion
		return []string{"why"}, cobra.ShellCompDirectiveDefault
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("withfile cmd called")
	},
}

func setFlags() {
	rootCmd.Flags().String("theme", "", "theme to use (located in /themes/THEMENAME/)")
	rootCmd.Flags().SetAnnotation("theme", cobra.BashCompSubdirsInDir, []string{"themes"})

	rootCmd.Flags().String("theme2", "", "theme to use (located in /themes/THEMENAME/)")
	rootCmd.RegisterFlagCompletionFunc("theme2", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return []string{"themes"}, cobra.ShellCompDirectiveFilterDirs
	})

	rootCmd.Flags().String("customComp", "", "test custom comp for flags")
	rootCmd.RegisterFlagCompletionFunc("customComp", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return []string{"firstComp\tthe first value", "secondComp\tthe second value", "forthComp\tthe forth value"}, cobra.ShellCompDirectiveNoFileComp
	})

	rootCmd.Flags().StringP("file", "f", "", "list files")
	rootCmd.Flags().String("longdesc", "", "before newline\nafter newline")

	rootCmd.Flags().BoolP("bool", "b", false, "bool flag")
	rootCmd.Flags().BoolSliceP("bslice", "B", nil, "bool slice flag")

	rootCmd.PersistentFlags().StringP("persistent", "p", "", "persistent flag")

	// rootCmd.Flags().String("required", "", "required flag")
	// rootCmd.MarkFlagRequired("required")

	vargsCmd.Flags().StringP("nonpersistent", "n", "", "non persistent local flag")

	// If there is only a recommended value before we reach the equal sign or the colon, then the completion works as expected.
	// If the values differ afterwards, completion fails in bash, but works in fish and zsh
	rootCmd.Flags().String("equalSignWorks", "", "test custom comp with equal sign")
	rootCmd.RegisterFlagCompletionFunc("equalSignWorks", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return []string{"first=Comp\tthe first value", "second=Comp\tthe second value", "forth=Comp\tthe forth value"}, cobra.ShellCompDirectiveNoFileComp
	})

	rootCmd.Flags().String("equalSignWorksNot", "", "test custom comp with equal sign")
	rootCmd.RegisterFlagCompletionFunc("equalSignWorksNot", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return []string{"first=Comp1\tthe first value", "first=Comp2\tthe second value", "first=Comp3\tthe forth value"}, cobra.ShellCompDirectiveNoFileComp
	})

	rootCmd.Flags().String("colonWorks", "", "test custom comp with colon one value works")
	rootCmd.RegisterFlagCompletionFunc("colonWorks", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return []string{"first:ONE\tthe first value", "second\tthe second value", "forth\tthe forth value"}, cobra.ShellCompDirectiveNoFileComp
	})

	rootCmd.Flags().String("colonWorksNot", "", "test custom comp with colon doesnt work")
	rootCmd.RegisterFlagCompletionFunc("colonWorksNot", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return []string{"first:ONE\tthe first value", "first:SECOND\tthe second value", "second:Comp1\tthe forth value"}, cobra.ShellCompDirectiveNoFileComp
	})

	rootCmd.Flags().String("nospace", "", "test custom comp with nospace directive")
	rootCmd.RegisterFlagCompletionFunc("nospace", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return []string{"complete\tFirst comp", "compost\tsecondComp"}, cobra.ShellCompDirectiveNoSpace
	})

	rootCmd.Flags().StringArray("array", []string{"allo", "toi"}, "string array flag")
}

func main() {
	completionCmd.Flags().BoolVar(
		&completionNoDesc,
		"no-descriptions", false,
		"disable completion description for shells that support it")
	rootCmd.AddCommand(completionCmd)

	rootCmd.AddCommand(
		filterFileCmd,
		noFileCmd,
		fullFileCmd,
		dirOnlyCmd,
		subdirCmd,
		compAndFileCmd,
		nodescriptionCmd,
		vargsCmd,
		colonCmd,
		aliasCmd,
		longDescCmd,
		specialCharDescCmd,
		noSpaceCmd,
		sentenceCmd,
		withfileCmd,
	)

	vargsCmd.AddCommand(childVargsCmd)
	setFlags()
	rootCmd.Execute()
}

@github-actions
Copy link

This PR is being marked as stale due to a long period of inactivity

@marckhouzam
Copy link
Collaborator Author

Waiting for review


set args (string split -- " " "$argv")
set args (string split -- " " (commandline -c))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that you are already touching this line can you change it to

Suggested change
set args (string split -- " " (commandline -c))
set args (string split -- " " (string trim (commandline -c)))

Please check #1303 for details. I already checked that both $argv or commandline -c have to be trimmed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Luap99 !
I will update with your findings.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it has to be:

Suggested change
set args (string split -- " " (commandline -c))
set args (string split -- " " (string trim -l (commandline -c)))

Only trim the left spaces as the right ones are required if complete an empty arg (e.g. command [TAB]).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.
Thanks again!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line should probably be set args (commandline -opc).
If the token at the cursor is really required, (commandline -ct) can be appended.

@marckhouzam marckhouzam changed the title Fix fish handling of "ShellCompDirectiveNoSpace" and file completion Fix multiple fish completion issues Dec 31, 2020
@marckhouzam
Copy link
Collaborator Author

This PR now addresses 5 different fish completion issues.

We have Go tests for the completion logic in Cobra that is coded in Go. Those tests can be found in custom_completions_test.go. However, we don't have tests to exercise the actual completion script coded in shell script. This makes it more difficult to make changes to those shell scripts without worrying about causing some regression.

To try to address this concern, I have setup a regression-testing project for the Cobra completion scripts.
It is currently able to test the fish and the bash scripts. Specifically for fish, it has tests that fail for each issue this PR is fixing and that pass with this PR applied. This gives me good confidence in this PR.

If anyone is interested it should be simple to run those tests locally:
https://github.com/marckhouzam/cobra-completion-testing

Copy link
Contributor

@Luap99 Luap99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Luap99
Copy link
Contributor

Luap99 commented Jan 24, 2021

@marckhouzam CI is red. You have to rebase.

Luap99 pushed a commit to Luap99/libpod that referenced this pull request Jan 24, 2021
Update the completion script like spf13/cobra#1249.

[NO TESTS NEEDED]

Fixes containers#8829

Signed-off-by: Paul Holzinger <paul.holzinger@web.de>
@@ -30,7 +30,7 @@ end
function __%[1]s_perform_completion
__%[1]s_debug "Starting __%[1]s_perform_completion"

set args (string split -- " " (commandline -c))
set args (string split -- " " (string trim -l (commandline -c)))
Copy link
Contributor

@krobelus krobelus Jan 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be string trim -- -l (commandline -cp)


Often it's not necessary to pass the current token to fish.
Rather, one can just compute all possible tokens because fish will filter them anyway.
Sometimes it can be useful to do the filtering in the app (for example if it's not feasible to enumerate all possible tokens), so it's fine. (the testprog examples show that the current token is necessary to complete --flags)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be string trim -- -l (commandline -cp)

I don't understand from the documentation what the -p flag does. Could you clarify?

Often it's not necessary to pass the current token to fish.
Rather, one can just compute all possible tokens because fish will filter them anyway.
Sometimes it can be useful to do the filtering in the app (for example if it's not feasible to enumerate all possible tokens), so it's fine. (the testprog examples show that the current token is necessary to complete --flags)

Right. So originally, I thought the program should do the filtering, but with experience, I now realize it is actually better to provide fish (and zsh) with all unfiltered completions so that the shell can do smarter matching than simply on prefix. For example, if the user types prog paw<TAB>, giving shell completions like bearpaw will allow it to still match even though it is not on the prefix.

As you saw in this PR however, I didn't find a way to find out if fish had found a smart match or not, so, when wanting to do file completion, I was forced to filter on prefix in the script itself, to know if there would be a match or not. This is because Cobra only wants to do file completion if there are no valid completions, so it can be consistent with bash and zsh. This was not ideal, so if you know of a way to figure out in the script if fish will match on a list of completion, that would be helpful.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The -p is explained in #1249 (comment). Sorry for the wall of text 😸

fish does fuzzy substring matching if there is no prefix or exact match. This is currently not exposed in a scriptable way.

I wonder if it's acceptable to do file completions only if there are no results. Doesn't sound too good, so probably the prefix comparison is better (maybe make that substring matching instead of only prefix).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be string trim -- -l (commandline -cp)

Aha, I get it now. Thanks. Yeah, that is important! I will add the -p.
I will also add a regression test for this case in https://github.com/marckhouzam/cobra-completion-testing

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it's acceptable to do file completions only if there are no results.

You mean if the program returns no completions? This is what the script does right now (before this PR). But that requires that the program do the filtering on itself. This PR is (in part) trying to improve that situation. By doing the filtering in the fish script, it will allow the program to return all completions, which will then allow the fuzzy matching you mention. The fuzzy matching will only not work when file completion is requested or when nospace is requested, both of which are the less common cases.

Doesn't sound too good, so probably the prefix comparison is better (maybe make that substring matching instead of only prefix).

As long as we use an algorithm that is stricter than what fish does, we could indeed improve compared to filtering on prefix. Do you know where I could see the algorithm used by fish? Or else I'll just play around and try to see if any pattern match seems to work.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify for myself; the common cases are

  • no files
  • only files because the program returns no completions

in those cases fish already does all the filtering. But if we're in between - the program returns some completions but they may not match the token - we want to filter in the completion script. That sounds great.

I agree that this is probably not very common. Most programs should take either custom tokens (like subcommands) or files, not both. Git is a notable exception, but Git completion computes custom file paths based on git ls-files.

I'd just ignore nospace for fish for now until, it behaves the right way most of the time already.
I can't think of a good solution right now, it needs support from fish.

Do you know where I could see the algorithm used by fish?

The two most permissive filters are here. I think they can be implemented like this:

$ function fishy_match -a needle haystack
      if string match -irq -- (string escape --style=regex -- $needle) $haystack
          echo substr match
      end
      if string match -rq -- (string split -- '' $needle | string escape --style=regex | string join '.*?') $haystack
          echo subseq match
      end
  end
$ fishy_match String 'case-insensitive substring match'
substr match
$ fishy_match foo follow
subseq match

I use -r and regex escaping because the needle might contain globs, which would be interpreted by string match without -r.

Copy link
Collaborator Author

@marckhouzam marckhouzam Jan 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most programs should take either custom tokens (like subcommands) or files, not both.

There are some cases where both are valid. Helm for example can accept the reference to a remote chart, or the local path to a chart. What I've done in helm is have the program return the list of files as completions to do both file completion and custom token completion.

I think it is important to keep all shells behaving the same for Cobra because the program returns a list of completions to be used by all shells; we don't want to make the program have to behave differently for each shell.

But we could, as a separate effort, support doing file completion even if there are custom token completion matches. This was not Cobra's previous behaviour, so I had never considered it myself, but I believe it could be done for all shells. Maybe a future effort...

I'd just ignore nospace for fish for now until, it behaves the right way most of the time already.
I can't think of a good solution right now, it needs support from fish.

Well, our current solution is good until fish 3.2. And then, when fish shows the choices including the fake one with a trailing ., it may be confusing, but I think it may be not much worse than letting the shell add and unwanted space.

DONE - I'll turn off adding the extra . when fish handles the case itself following the characters you mentioned.

PENDING - And I'll also adapt the filtering based on the algos you've provided.

I feel that after all that, we'll have something really solid for fish completion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I've done in helm is have the program return the list of files as completions to do both file completion and custom token completion.

Ideally we could tell the shell that we also want file completons, because it can see through variables to tokens like $PWD/. Something for the future I guess. The implementation would be a bit hacky:
essentially, you'd need two calls to complete -c, one with -f and one without.
Each of them has a condition (the -n part). If the condition for the one with file completions is true, then fish will also provide file completions (in addition to the provided custom completions).

we don't want to make the program have to behave differently for each shell.

In terms of what completions to offer, definitely. Of course shells differ in how they display completions.
By default, fish sorts completions, but you can add the --keep-order flag to the complete -c call, then the program is in control of the ordering.

I feel that after all that, we'll have something really solid for fish completion.

Yeah, latest changes look great! For some programs it's hard to compete with manually written completions, but it should work great for conventional programs.

fish_completions.go Show resolved Hide resolved
fish_completions.go Outdated Show resolved Hide resolved
# by outputting an extra, longer completion.
# We must first split on \t to get rid of the descriptions because
# the extra character we add to the fake second completion must be
# before the description. We don't need descriptions anyway since
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clever, and works reliably as far as I can tell.
However, the upcoming fish 3.2.0 will always show the pager on ambiguous completions (fish-shell/fish-shell#6924). This would cause some confusion.

So I'm not sure if this an overall improvement. Who are the users of this option?
Fish already gets this right a lot of times by hardcoding the character set @=/:., - if a completion ends in one of these characters, then no space will be inserted.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clever, and works reliably as far as I can tell.
However, the upcoming fish 3.2.0 will always show the pager on ambiguous completions (fish-shell/fish-shell#6924). This would cause some confusion.

Ouch, that will indeed cause confusion for the "nospace" case.

So I'm not sure if this an overall improvement. Who are the users of this option?

For example, Helm uses this option when completing a chart's full name which is comprised of <repository>/<chartname>; the completion first provides all repository names in the form <repository>/, and once the slash is present on the command-line, the completion will add the possible chart names, but there should be no space between the two. This is much more efficient for helm than having to provide all the full <repository>/<chartname> from the very start.

kubectl cp <pod>:<file> could also use this option to avoid adding a space after the :.

Fish already gets this right a lot of times by hardcoding the character set @=/:., - if a completion ends in one of these characters, then no space will be inserted.

Cool! I was not aware of this. This would address both cases I mentioned. I tested it and it works as you describe.
But I don't know if there are other cases that wouldn't end with @=/:.,. At a minimum, we could turn off this hack for if the completion ended with @=/:.,. I'll have to think what to do for the other (possible) cases for fish 3.2. Let me know if you have any suggestions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One could sidestep the completion engine and directly insert the unique completion if nospace is set

$ function sneaky-complete
      commandline --replace -t nospace
  end
$ complete -e sneaky-complete; complete -c sneaky-complete -a '(sneaky-complete)' -f

According to my tests this works (although it rings the terminal bell, because fish thinks there are no completions). However, I'd advise against it. You are not meant to modifiy the commandline during the computation of a completion. That can break other completions, though I didn't find an example here.

fish has not added an option to control the add-a-space behavior yet because AFAIK no real use case has been brought up that doesn't work with the hardcoded list.

I fear that the cost of adding a hack to support this outweighs the benefits.
I think we should drop this until we see a real need. Then an option can be added to fish, avoiding the need for a hacky workaround.

Copy link
Contributor

@Luap99 Luap99 Jan 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a look how I use the ShellCompDirectiveNoSpace option in podman. Almost all cases ends with one of =:, but not all. I found one case where I set this when it ends with a -. https://github.com/containers/podman/blob/479fc226044b745ecaafc2d5fa925afe6ca06de0/cmd/podman/common/completion.go#L603-L608
Even more importantly there is a case where I set this together with ShellCompDirectiveDefault (path completion). This case does not work with fish currently. It works for bash with @marckhouzam bashV2 PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for investigating. I guess we should just add - to the set of separators in fish.

Regarding the nospace+path, is this what you mean:

// cobra-completion-testing/testprog/testprog.go
var noSpaceCmdPrefix = &cobra.Command{
	Use:   "nospace",
	Short: "Directive: no space",
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return nil, cobra.ShellCompDirectiveNoSpace
	},
	Run: func(cmd *cobra.Command, args []string) {},
}
testprog/bin/testprog prefix nospace <TAB>

this gives me files in both fish and bash (I've merged this branch and the bash v2 one).
If I return some completions instead of nil, then I only get those completions in both shells (as expected).

You probably mean something else?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly I don't think adding - make much sense. This might solve my specific problem but doesn't solve the problem here.
cobra allows me as developer to set nospace wherever I want, not only on those characters. I don't see a reason why fish should limit my options as a completion script developer.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even more importantly there is a case where I set this together with ShellCompDirectiveDefault (path completion).
Bash does not add a space after the completed path. Fish does.

@Luap99 I never planned for this case. And now that you mention it, I realize it also does not work for zsh. It is an easy fix though. I will add it to #1213. And I see that you made it work for powershell 🎉 . I don't believe there is anything we can do for fish though.

Out of curiosity, what kind of situation would not want a space after file completion?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out preventing a space after file completion for zsh also prevents the trailing / from being added after a directory. At least in the way I've found to prevent a space. I think a missing / is a bigger problem than the extra space, so I'll leave it alone.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To get back to the 'nospace' directive for fish, the latest version of this PR keeps the "hack" that adds an extra fake completion but only when the completion does not end with @=/:.,. I think this is the best we can do at this time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, what kind of situation would not want a space after file completion?

Simple answer podman/docker run --volume. This flag accepts a volume name or a path followed by a colon and again a path. This is my current autocompletion function:

func AutocompleteVolumeFlag(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
	volumes, _ := getVolumes(cmd, toComplete)
	directive := cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveDefault
	if strings.Contains(toComplete, ":") {
		// add space after second path
		directive = cobra.ShellCompDirectiveDefault
	}
	return volumes, directive
}

After the first path I do not want the space added. The user has to type a colon here. After the colon you get only path completion and then I a space should be added.

Turns out preventing a space after file completion for zsh also prevents the trailing / from being added after a directory. At least in the way I've found to prevent a space. I think a missing / is a bigger problem than the extra space, so I'll leave it alone.

I am totally fine if it does not work. It is just a small corner case.

fish_completions.go Outdated Show resolved Hide resolved
ti-chi-bot bot referenced this pull request in PingCAP-QE/ee-apps Dec 9, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [github.com/spf13/cobra](https://github.com/spf13/cobra) | require |
minor | `v1.1.3` -> `v1.8.0` |

---

### Release Notes

<details>
<summary>spf13/cobra (github.com/spf13/cobra)</summary>

### [`v1.8.0`](https://github.com/spf13/cobra/releases/tag/v1.8.0)

[Compare
Source](https://github.com/spf13/cobra/compare/v1.7.0...v1.8.0)

#### ✨ Features

- Support usage as plugin for tools like kubectl by
[@&#8203;nirs](https://github.com/nirs) in
[https://github.com/spf13/cobra/pull/2018](https://github.com/spf13/cobra/pull/2018)
- this means that programs that utilize a "plugin-like" structure have
much better support and usage (like for completions, command paths,
etc.)
- Move documentation sources to site/content by
[@&#8203;umarcor](https://github.com/umarcor) in
[https://github.com/spf13/cobra/pull/1428](https://github.com/spf13/cobra/pull/1428)
- Add 'one required flag' group by
[@&#8203;marevers](https://github.com/marevers) in
[https://github.com/spf13/cobra/pull/1952](https://github.com/spf13/cobra/pull/1952)
- this includes a new `MarkFlagsOneRequired` API for flags which can be
used to mark a flag group as required and cause command failure if at
least one is not used when invoked.
- Customizable error message prefix by
[@&#8203;5ouma](https://github.com/5ouma) in
[https://github.com/spf13/cobra/pull/2023](https://github.com/spf13/cobra/pull/2023)
- This adds the `SetErrPrefix` and `ErrPrefix` APIs on the `Command`
struct to allow for setting a custom prefix for errors
- feat: add getters for flag completions by
[@&#8203;avirtopeanu-ionos](https://github.com/avirtopeanu-ionos) in
[https://github.com/spf13/cobra/pull/1943](https://github.com/spf13/cobra/pull/1943)
- Feature: allow running persistent run hooks of all parents by
[@&#8203;vkhoroz](https://github.com/vkhoroz) in
[https://github.com/spf13/cobra/pull/2044](https://github.com/spf13/cobra/pull/2044)
- Improve API to get flag completion function by
[@&#8203;marckhouzam](https://github.com/marckhouzam) in
[https://github.com/spf13/cobra/pull/2063](https://github.com/spf13/cobra/pull/2063)

#### 🐛 Bug fixes

- Fix typo in fish completions by
[@&#8203;twpayne](https://github.com/twpayne) in
[https://github.com/spf13/cobra/pull/1945](https://github.com/spf13/cobra/pull/1945)
- Fix grammar: 'allows to' by
[@&#8203;supertassu](https://github.com/supertassu) in
[https://github.com/spf13/cobra/pull/1978](https://github.com/spf13/cobra/pull/1978)
- powershell: escape variable with curly brackets by
[@&#8203;Luap99](https://github.com/Luap99) in
[https://github.com/spf13/cobra/pull/1960](https://github.com/spf13/cobra/pull/1960)
- Don't complete --help flag when flag parsing disabled by
[@&#8203;marckhouzam](https://github.com/marckhouzam) in
[https://github.com/spf13/cobra/pull/2061](https://github.com/spf13/cobra/pull/2061)
- Replace all non-alphanumerics in active help env var program prefix by
[@&#8203;scop](https://github.com/scop) in
[https://github.com/spf13/cobra/pull/1940](https://github.com/spf13/cobra/pull/1940)

#### 🔧 Maintenance

- build(deps): bump golangci/golangci-lint-action from 3.4.0 to 3.5.0 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/spf13/cobra/pull/1971](https://github.com/spf13/cobra/pull/1971)
- build(deps): bump golangci/golangci-lint-action from 3.5.0 to 3.6.0 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/spf13/cobra/pull/1976](https://github.com/spf13/cobra/pull/1976)
- build(deps): bump golangci/golangci-lint-action from 3.6.0 to 3.7.0 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/spf13/cobra/pull/2021](https://github.com/spf13/cobra/pull/2021)
- build(deps): bump actions/setup-go from 3 to 4 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/spf13/cobra/pull/1934](https://github.com/spf13/cobra/pull/1934)
- build(deps): bump github.com/cpuguy83/go-md2man/v2 from 2.0.2 to 2.0.3
by [@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/spf13/cobra/pull/2047](https://github.com/spf13/cobra/pull/2047)
- build(deps): bump actions/checkout from 3 to 4 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/spf13/cobra/pull/2028](https://github.com/spf13/cobra/pull/2028)
- command: temporarily disable G602 due to
[securego/gosec#1005](https://github.com/securego/gosec/issues/1005)
by [@&#8203;umarcor](https://github.com/umarcor) in
[https://github.com/spf13/cobra/pull/2022](https://github.com/spf13/cobra/pull/2022)

#### 🧪 Testing & CI/CD

- test: make fish_completions_test more robust by
[@&#8203;branchvincent](https://github.com/branchvincent) in
[https://github.com/spf13/cobra/pull/1980](https://github.com/spf13/cobra/pull/1980)
- golangci: enable 'unused' and disable deprecated replaced by it by
[@&#8203;umarcor](https://github.com/umarcor) in
[https://github.com/spf13/cobra/pull/1983](https://github.com/spf13/cobra/pull/1983)
- cleanup: minor corrections to unit tests by
[@&#8203;JunNishimura](https://github.com/JunNishimura) in
[https://github.com/spf13/cobra/pull/2003](https://github.com/spf13/cobra/pull/2003)
- ci: test golang 1.21 by
[@&#8203;nunoadrego](https://github.com/nunoadrego) in
[https://github.com/spf13/cobra/pull/2024](https://github.com/spf13/cobra/pull/2024)
- Fix linter errors by
[@&#8203;marckhouzam](https://github.com/marckhouzam) in
[https://github.com/spf13/cobra/pull/2052](https://github.com/spf13/cobra/pull/2052)
- Add tests for flag completion registration by
[@&#8203;marckhouzam](https://github.com/marckhouzam) in
[https://github.com/spf13/cobra/pull/2053](https://github.com/spf13/cobra/pull/2053)

#### ✏️ Documentation

- doc: fix typo, Deperecated -> Deprecated by
[@&#8203;callthingsoff](https://github.com/callthingsoff) in
[https://github.com/spf13/cobra/pull/2000](https://github.com/spf13/cobra/pull/2000)
- Add notes to doc about the execution condition of \*PreRun and
\*PostRun functions by
[@&#8203;haoming29](https://github.com/haoming29) in
[https://github.com/spf13/cobra/pull/2041](https://github.com/spf13/cobra/pull/2041)

***

Thank you everyone who contributed to this release and all your hard
work! Cobra and this community would never be possible without all of
you!!!! 🐍

**Full Changelog**:
spf13/cobra@v1.7.0...v1.8.0

### [`v1.7.0`](https://github.com/spf13/cobra/releases/tag/v1.7.0)

[Compare
Source](https://github.com/spf13/cobra/compare/v1.6.1...v1.7.0)

##### ✨ Features

- Allow to preserve ordering of completions in `bash`, `zsh`, `pwsh`, &
`fish`: [@&#8203;h4ck3rk3y](https://github.com/h4ck3rk3y)
[#&#8203;1903](https://github.com/spf13/cobra/issues/1903)
- Add support for PowerShell 7.2+ in completions:
[@&#8203;oldium](https://github.com/oldium)
[#&#8203;1916](https://github.com/spf13/cobra/issues/1916)
- Allow sourcing zsh completion script:
[@&#8203;marckhouzam](https://github.com/marckhouzam)
[#&#8203;1917](https://github.com/spf13/cobra/issues/1917)

##### 🐛 Bug fixes

- Don't remove flag values that match sub-command name:
[@&#8203;brianpursley](https://github.com/brianpursley)
[#&#8203;1781](https://github.com/spf13/cobra/issues/1781)
- Fix powershell completions not returning single word:
[@&#8203;totkeks](https://github.com/totkeks)
[#&#8203;1850](https://github.com/spf13/cobra/issues/1850)
- Remove masked `template` import variable name:
[@&#8203;yashLadha](https://github.com/yashLadha)
[#&#8203;1879](https://github.com/spf13/cobra/issues/1879)
- Correctly detect completions with dash in argument:
[@&#8203;oncilla](https://github.com/oncilla)
[#&#8203;1817](https://github.com/spf13/cobra/issues/1817)

##### 🧪 Testing & CI/CD

- Deprecate Go 1.15 in CI:
[@&#8203;umarcor](https://github.com/umarcor)
[#&#8203;1866](https://github.com/spf13/cobra/issues/1866)
- Deprecate Go 1.16 in CI:
[@&#8203;umarcor](https://github.com/umarcor)
[#&#8203;1926](https://github.com/spf13/cobra/issues/1926)
- Add testing for Go 1.20 in CI:
[@&#8203;umarcor](https://github.com/umarcor)
[#&#8203;1925](https://github.com/spf13/cobra/issues/1925)
- Add tests to illustrate unknown flag bug:
[@&#8203;brianpursley](https://github.com/brianpursley)
[#&#8203;1854](https://github.com/spf13/cobra/issues/1854)

##### 🔧 Maintenance

- Update main image to better handle dark backgrounds:
[@&#8203;Deleplace](https://github.com/Deleplace) and
[@&#8203;marckhouzam](https://github.com/marckhouzam)
[#&#8203;1883](https://github.com/spf13/cobra/issues/1883)
- Fix `stale.yaml` mispellings:
[@&#8203;enrichman](https://github.com/enrichman)
[#&#8203;1863](https://github.com/spf13/cobra/issues/1863)
- Remove stale bot from GitHub actions:
[@&#8203;jpmcb](https://github.com/jpmcb)
[#&#8203;1908](https://github.com/spf13/cobra/issues/1908)
- Add makefile target for installing dependencies:
[@&#8203;umarcor](https://github.com/umarcor)
[#&#8203;1865](https://github.com/spf13/cobra/issues/1865)
- Add Sia to projects using Cobra:
[@&#8203;mike76-dev](https://github.com/mike76-dev)
[#&#8203;1844](https://github.com/spf13/cobra/issues/1844)
- Add `Vitess` and `Arewefastyet` to projects using cobra:
[@&#8203;frouioui](https://github.com/frouioui)
[#&#8203;1932](https://github.com/spf13/cobra/issues/1932)
- Fixup for Kubescape github org:
[@&#8203;dwertent](https://github.com/dwertent)
[#&#8203;1874](https://github.com/spf13/cobra/issues/1874)
- Fix route for GitHub workflows badge:
[@&#8203;sh-cho](https://github.com/sh-cho)
[#&#8203;1884](https://github.com/spf13/cobra/issues/1884)
- Fixup for GoDoc style documentation:
[@&#8203;yashLadha](https://github.com/yashLadha)
[#&#8203;1885](https://github.com/spf13/cobra/issues/1885)
- Various bash scripting improvements for completion:
[@&#8203;scop](https://github.com/scop)
[#&#8203;1702](https://github.com/spf13/cobra/issues/1702)
- Add Constellation to projects using Cobra:
[@&#8203;datosh](https://github.com/datosh)
[#&#8203;1829](https://github.com/spf13/cobra/issues/1829)

##### ✏️ Documentation

- Add documentation about disabling completion descriptions:
[@&#8203;Shihta](https://github.com/Shihta)
[#&#8203;1901](https://github.com/spf13/cobra/issues/1901)
- Improve `MarkFlagsMutuallyExclusive` example in user guide:
[@&#8203;janhn](https://github.com/janhn)
[#&#8203;1904](https://github.com/spf13/cobra/issues/1904)
- Update `shell_completions.md`:
[@&#8203;gusega](https://github.com/gusega)
[#&#8203;1907](https://github.com/spf13/cobra/issues/1907)
- Update copywrite year: [@&#8203;umarcor](https://github.com/umarcor)
[#&#8203;1927](https://github.com/spf13/cobra/issues/1927)
- Document suggested layout of subcommands:
[@&#8203;lcarva](https://github.com/lcarva)
[#&#8203;1930](https://github.com/spf13/cobra/issues/1930)
- Replace deprecated ExactValidArgs with MatchAll in doc:
[@&#8203;doniacld](https://github.com/doniacld)
[#&#8203;1836](https://github.com/spf13/cobra/issues/1836)

***

This release contains several long running fixes, improvements to
powershell completions, and further optimizations for completions.

Thank you everyone who contributed to this release and all your hard
work! Cobra and this community would never be possible without all of
you! 🐍

Full changelog:  spf13/cobra@v1.6.1...v1.7.0

### [`v1.6.1`](https://github.com/spf13/cobra/releases/tag/v1.6.1)

[Compare
Source](https://github.com/spf13/cobra/compare/v1.6.0...v1.6.1)

##### Bug fixes 🐛

- Fixes a panic when `AddGroup` isn't called before
`AddCommand(my-sub-command)` is executed. This can happen within more
complex cobra file structures that have many different `init`s to be
executed. Now, the check for groups has been moved to `ExecuteC` and
provides more flexibility when working with grouped commands -
[@&#8203;marckhouzam](https://github.com/marckhouzam) (and shout out
to [@&#8203;aawsome](https://github.com/aawsome),
[@&#8203;andig](https://github.com/andig) and
[@&#8203;KINGSABRI](https://github.com/KINGSABRI) for a deep
investigation into this! 👏🏼)

### [`v1.6.0`](https://github.com/spf13/cobra/releases/tag/v1.6.0)

[Compare
Source](https://github.com/spf13/cobra/compare/v1.5.0...v1.6.0)

##### Summer 2022 Release

Some exciting changes make their way to Cobra! Command completions
continue to get better and better (including adding `--help` and
`--version` automatic flags to the completions list). Grouping is now
possible in your help output as well! And you can now use the
`OnFinalize` method to cleanup things when all "work" is done. Checkout
the full changelog below:

***

##### Features 🌠

- Add groups for commands in help:
[@&#8203;aawsome](https://github.com/aawsome)
[@&#8203;marckhouzam](https://github.com/marckhouzam)
[#&#8203;1003](https://github.com/spf13/cobra/issues/1003)
- Support for case-insensitive command names:
[@&#8203;YuviGold](https://github.com/YuviGold)
[#&#8203;1802](https://github.com/spf13/cobra/issues/1802)
- Expose `ValidateRequiredFlags` and `ValidateFlagGroups`:
[@&#8203;skeetwu](https://github.com/skeetwu)
[#&#8203;1760](https://github.com/spf13/cobra/issues/1760)
- Add `--version` flag to help output:
[@&#8203;fnickels](https://github.com/fnickels)
[#&#8203;1707](https://github.com/spf13/cobra/issues/1707)
- Add `--help` and `--version` flag in completions:
[@&#8203;marckhouzam](https://github.com/marckhouzam)
[#&#8203;1813](https://github.com/spf13/cobra/issues/1813)
- Add `OnFinalize` method:
[@&#8203;yann-soubeyrand](https://github.com/yann-soubeyrand)
[#&#8203;1788](https://github.com/spf13/cobra/issues/1788)
- Allow user to add completion for powershell alias:
[@&#8203;marckhouzam](https://github.com/marckhouzam)
[#&#8203;1621](https://github.com/spf13/cobra/issues/1621)
- Make `InitDefaultcompletionCmd` public:
[@&#8203;gssbzn](https://github.com/gssbzn)
[#&#8203;1467](https://github.com/spf13/cobra/issues/1467)

##### Deprecation 👎🏼

- `ExactValidArgs` is deprecated (but not being removed entirely). This
is abit nuanced, so checkout
[#&#8203;1643](https://github.com/spf13/cobra/issues/1643) for further
information and the [updated
`user_guide.md`](https://github.com/spf13/cobra/blob/main/user_guide.md)
on how this may affect you (and how you can take advantage of the
*correct* behavior in the validators):
[@&#8203;umarcor](https://github.com/umarcor)
[#&#8203;1643](https://github.com/spf13/cobra/issues/1643)

##### Bug fixes 🐛

- Fix (bash-v2) `activeHelp` length check syntax:
[@&#8203;scop](https://github.com/scop)
[#&#8203;1762](https://github.com/spf13/cobra/issues/1762)
- Fix correct command path in `see_also` for yaml documentation:
[@&#8203;zregvart](https://github.com/zregvart)
[#&#8203;1771](https://github.com/spf13/cobra/issues/1771)
- Fix showing flags that shadow parent persistent flag in child help
messaging: [@&#8203;brianpursley](https://github.com/brianpursley)
[#&#8203;1776](https://github.com/spf13/cobra/issues/1776)

##### Dependencies 🗳️

- Upgrade to use `gopkg.in/yaml.v3`:
[@&#8203;tklauser](https://github.com/tklauser)
[#&#8203;1766](https://github.com/spf13/cobra/issues/1766)

##### Testing 🤔

- Test on Golang 1.19: [@&#8203;umarcor](https://github.com/umarcor) &
[@&#8203;jpmcb](https://github.com/jpmcb)
[#&#8203;1782](https://github.com/spf13/cobra/issues/1782)
- Renamed powershell completion tests:
[@&#8203;marckhouzam](https://github.com/marckhouzam)
[#&#8203;1803](https://github.com/spf13/cobra/issues/1803)
- Use `action/setup-go` cache:
[@&#8203;umarcor](https://github.com/umarcor)
[#&#8203;1783](https://github.com/spf13/cobra/issues/1783)
- Add `workflow_dispatch` to CI actions:
[@&#8203;umarcor](https://github.com/umarcor)
[#&#8203;1387](https://github.com/spf13/cobra/issues/1387)
- Add minimum GitHub token permissions for workflows:
[@&#8203;varunsh-coder](https://github.com/varunsh-coder)
[#&#8203;1792](https://github.com/spf13/cobra/issues/1792)

##### Docs ✏️

- Fixup spelling for GitHub CLI:
[@&#8203;eltociear](https://github.com/eltociear)
[#&#8203;1744](https://github.com/spf13/cobra/issues/1744)
- Clarify `SetContext` documentation:
[@&#8203;katexochen](https://github.com/katexochen)
[#&#8203;1748](https://github.com/spf13/cobra/issues/1748)
- Instruct user to `go install` for binary:
[@&#8203;marckhouzam](https://github.com/marckhouzam)
[#&#8203;1726](https://github.com/spf13/cobra/issues/1726)
- User guide cleanup:
[@&#8203;marckhouzam](https://github.com/marckhouzam)
[#&#8203;1656](https://github.com/spf13/cobra/issues/1656)
- Document option to hide the default completion command:
[@&#8203;marckhouzam](https://github.com/marckhouzam)
[#&#8203;1779](https://github.com/spf13/cobra/issues/1779)

##### Misc 💭

- Add KubeVirt, CloudQuery, Cilium, Okteto, Zitadel, Allero to projects
using cobra: [@&#8203;maiqueb](https://github.com/maiqueb)
[#&#8203;1741](https://github.com/spf13/cobra/issues/1741),
[@&#8203;yevgenypats](https://github.com/yevgenypats)
[#&#8203;1742](https://github.com/spf13/cobra/issues/1742),
[@&#8203;tklauser](https://github.com/tklauser)
[#&#8203;1745](https://github.com/spf13/cobra/issues/1745),
[@&#8203;jLopezbarb](https://github.com/jLopezbarb)
[#&#8203;1759](https://github.com/spf13/cobra/issues/1759),
[@&#8203;fforootd](https://github.com/fforootd)
[#&#8203;1772](https://github.com/spf13/cobra/issues/1772),
[@&#8203;dimabru](https://github.com/dimabru)
[#&#8203;1819](https://github.com/spf13/cobra/issues/1819)
- Use correct stale action `exempt` yaml keys:
[@&#8203;jpmcb](https://github.com/jpmcb)
[#&#8203;1800](https://github.com/spf13/cobra/issues/1800)
- Add missing license headers:
[@&#8203;umarcor](https://github.com/umarcor)
[#&#8203;1809](https://github.com/spf13/cobra/issues/1809)

*Note:* Per
[#&#8203;1804](https://github.com/spf13/cobra/issues/1804), we will be
moving away from "seasonal" releases and doing more generic point
release targets. Continue to track the milestones and issues in the
`spf13/cobra` GitHub repository for more information!

Great work everyone! Cobra would never be possible without your
contributions! 🐍

**Full Changelog**:
spf13/cobra@v1.5.0...v1.6.0

### [`v1.5.0`](https://github.com/spf13/cobra/releases/tag/v1.5.0)

[Compare
Source](https://github.com/spf13/cobra/compare/v1.4.0...v1.5.0)

#### Spring 2022 Release 🌥️

Hello everyone! Welcome to another release of cobra. Completions
continue to get better and better. This release adds a few really cool
new features. We also continue to patch versions of our dependencies as
they become available via dependabot. Happy coding!

#### Active help 👐🏼

Shout out to [@&#8203;marckhouzam](https://github.com/marckhouzam) for
a big value add: Active Help
[https://github.com/spf13/cobra/pull/1482](https://github.com/spf13/cobra/pull/1482).
With active help, a program can provide some inline warnings or hints
for users as they hit tab. Now, your CLIs can be even more intuitive to
use!

Currently active help is only supported for bash V2 and zsh. Marc wrote
a whole guide on how to do this, so make sure to give it a good read to
learn how you can add this to your cobra code!
https://github.com/spf13/cobra/blob/master/active_help.md

#### Group flags 🧑🏼‍🤝‍🧑🏼

Cobra now has the ability to mark flags as required or exclusive as a
***group***. Shout out to our newest maintainer
[@&#8203;johnSchnake](https://github.com/johnSchnake) for this!
[https://github.com/spf13/cobra/pull/1654](https://github.com/spf13/cobra/pull/1654)
Let's say you have a `username` flag that ***MUST*** be partnered with a
`password` flag. Well, now, you can enforce those as being required
together:

```go
rootCmd.Flags().StringVarP(&u, "username", "u", "", "Username (required if password is set)")
rootCmd.Flags().StringVarP(&pw, "password", "p", "", "Password (required if username is set)")
rootCmd.MarkFlagsRequiredTogether("username", "password")
```

Flags may also be marked as "mutally exclusive" with the
`MarkFlagsMutuallyExclusive(string, string ... )` command API. Refer to
our [user guide
documentation](https://github.com/spf13/cobra/blob/master/user_guide.md)
for further info!

#### Completions 👀

- Add backwards-compatibility tests for legacyArgs() by
[@&#8203;marckhouzam](https://github.com/marckhouzam) in
[https://github.com/spf13/cobra/pull/1547](https://github.com/spf13/cobra/pull/1547)
- feat: Add how to load completions in your current zsh session by
[@&#8203;ondrejsika](https://github.com/ondrejsika) in
[https://github.com/spf13/cobra/pull/1608](https://github.com/spf13/cobra/pull/1608)
- Introduce FixedCompletions by
[@&#8203;emersion](https://github.com/emersion) in
[https://github.com/spf13/cobra/pull/1574](https://github.com/spf13/cobra/pull/1574)
- Add shell completion to flag groups by
[@&#8203;marckhouzam](https://github.com/marckhouzam) in
[https://github.com/spf13/cobra/pull/1659](https://github.com/spf13/cobra/pull/1659)
- Modify brew prefix path in macOS system by
[@&#8203;imxw](https://github.com/imxw) in
[https://github.com/spf13/cobra/pull/1719](https://github.com/spf13/cobra/pull/1719)
- perf(bash-v2): use backslash escape string expansion for tab by
[@&#8203;scop](https://github.com/scop) in
[https://github.com/spf13/cobra/pull/1682](https://github.com/spf13/cobra/pull/1682)
- style(bash-v2): out is not an array variable, do not refer to it as
such by [@&#8203;scop](https://github.com/scop) in
[https://github.com/spf13/cobra/pull/1681](https://github.com/spf13/cobra/pull/1681)
- perf(bash-v2): standard completion optimizations by
[@&#8203;scop](https://github.com/scop) in
[https://github.com/spf13/cobra/pull/1683](https://github.com/spf13/cobra/pull/1683)
- style(bash): out is not an array variable, do not refer to it as such
by [@&#8203;scop](https://github.com/scop) in
[https://github.com/spf13/cobra/pull/1684](https://github.com/spf13/cobra/pull/1684)
- perf(bash-v2): short-circuit descriptionless candidate lists by
[@&#8203;scop](https://github.com/scop) in
[https://github.com/spf13/cobra/pull/1686](https://github.com/spf13/cobra/pull/1686)
- perf(bash-v2): speed up filtering entries with descriptions by
[@&#8203;scop](https://github.com/scop) in
[https://github.com/spf13/cobra/pull/1689](https://github.com/spf13/cobra/pull/1689)
- perf(bash-v2): speed up filtering menu-complete descriptions by
[@&#8203;scop](https://github.com/scop) in
[https://github.com/spf13/cobra/pull/1692](https://github.com/spf13/cobra/pull/1692)
- fix(bash-v2): skip empty completions when filtering descriptions by
[@&#8203;scop](https://github.com/scop) in
[https://github.com/spf13/cobra/pull/1691](https://github.com/spf13/cobra/pull/1691)
- perf(bash-v2): read directly to COMPREPLY on descriptionless short
circuit by [@&#8203;scop](https://github.com/scop) in
[https://github.com/spf13/cobra/pull/1700](https://github.com/spf13/cobra/pull/1700)
- fix: Don't complete \_command on zsh by
[@&#8203;twpayne](https://github.com/twpayne) in
[https://github.com/spf13/cobra/pull/1690](https://github.com/spf13/cobra/pull/1690)
- Improve fish_completions code quality by
[@&#8203;t29kida](https://github.com/t29kida) in
[https://github.com/spf13/cobra/pull/1515](https://github.com/spf13/cobra/pull/1515)
- Fix handling of descriptions for bash v3 by
[@&#8203;marckhouzam](https://github.com/marckhouzam) in
[https://github.com/spf13/cobra/pull/1735](https://github.com/spf13/cobra/pull/1735)
- undefined or nil Args default to ArbitraryArgs by
[@&#8203;umarcor](https://github.com/umarcor) in
[https://github.com/spf13/cobra/pull/1612](https://github.com/spf13/cobra/pull/1612)
- Add Command.SetContext by
[@&#8203;joshcarp](https://github.com/joshcarp) in
[https://github.com/spf13/cobra/pull/1551](https://github.com/spf13/cobra/pull/1551)
- Wrap printf tab with quotes by
[@&#8203;PapaCharlie](https://github.com/PapaCharlie) in
[https://github.com/spf13/cobra/pull/1665](https://github.com/spf13/cobra/pull/1665)

#### Documentation 📝

- Fixed typos in completions docs -
[@&#8203;cuishuang](https://github.com/cuishuang)
[https://github.com/spf13/cobra/pull/1625](https://github.com/spf13/cobra/pull/1625)
- Removed `CHANGELOG.md` as it isn't updated -
[@&#8203;johnSchnake](https://github.com/johnSchnake)
[https://github.com/spf13/cobra/pull/1634](https://github.com/spf13/cobra/pull/1634)
- Minor typo fix in `shell_completion.md` -
[@&#8203;danieldn](https://github.com/danieldn)
[https://github.com/spf13/cobra/pull/1678](https://github.com/spf13/cobra/pull/1678)
- Changed branch name in the cobra generator link to 'main' -
[@&#8203;skywalker2909](https://github.com/skywalker2909)
[https://github.com/spf13/cobra/pull/1645](https://github.com/spf13/cobra/pull/1645)
- Fix Command.Context comment by
[@&#8203;katexochen](https://github.com/katexochen) in
[https://github.com/spf13/cobra/pull/1639](https://github.com/spf13/cobra/pull/1639)
- Change appropriate links from http:// to https:// where applicable -
[@&#8203;deining](https://github.com/deining)
[https://github.com/spf13/cobra/pull/1695](https://github.com/spf13/cobra/pull/1695)

#### Testing & CI ⚙️

- Test on Golang 1.18 - [@&#8203;umarcor](https://github.com/umarcor)
[https://github.com/spf13/cobra/pull/1635](https://github.com/spf13/cobra/pull/1635)
- Use `RICHGO_FORCE_COLOR` -
[@&#8203;umarcor](https://github.com/umarcor)
[https://github.com/spf13/cobra/pull/1647](https://github.com/spf13/cobra/pull/1647)
- Adds size labeler GitHub action by
[@&#8203;jpmcb](https://github.com/jpmcb) in
[https://github.com/spf13/cobra/pull/1610](https://github.com/spf13/cobra/pull/1610)
- Update `stale-bot` settings -
[@&#8203;jpmcb](https://github.com/jpmcb)
[https://github.com/spf13/cobra/pull/1609](https://github.com/spf13/cobra/pull/1609)

#### Beep boop, bot commits 🤖

- Bumped golangci/golangci-lint-action from 3.1.0 to 3.2.0 -
[@&#8203;dependabot](https://github.com/dependabot)
[https://github.com/spf13/cobra/pull/1697](https://github.com/spf13/cobra/pull/1697)
- Bump codelytv/pr-size-labeler from 1.8.0 to 1.8.1 -
[@&#8203;dependabot](https://github.com/dependabot)
[https://github.com/spf13/cobra/pull/1661](https://github.com/spf13/cobra/pull/1661)
- Bump actions/stale from 1 to 5 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/spf13/cobra/pull/1618](https://github.com/spf13/cobra/pull/1618)
- Bump actions/cache from 2 to 3 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/spf13/cobra/pull/1640](https://github.com/spf13/cobra/pull/1640)
- Bump actions/labeler from 3 to 4 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/spf13/cobra/pull/1620](https://github.com/spf13/cobra/pull/1620)
- Bump golangci/golangci-lint-action from 2 to 3.1.0 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/spf13/cobra/pull/1615](https://github.com/spf13/cobra/pull/1615)
- Bump actions/checkout from 2 to 3 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/spf13/cobra/pull/1619](https://github.com/spf13/cobra/pull/1619)
- Bump github.com/cpuguy83/go-md2man/v2 from 2.0.1 to 2.0.2 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/spf13/cobra/pull/1688](https://github.com/spf13/cobra/pull/1688)
- Bump actions/setup-go from 2 to 3 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/spf13/cobra/pull/1660](https://github.com/spf13/cobra/pull/1660)

#### Misc 💭

- Use `errors.Is()` to check for errors -
[@&#8203;Luap99](https://github.com/Luap99)
[https://github.com/spf13/cobra/pull/1730](https://github.com/spf13/cobra/pull/1730)
- Prefer ReplaceAll instead of Replace(..., -1) by
[@&#8203;WhyNotHugo](https://github.com/WhyNotHugo) in
[https://github.com/spf13/cobra/pull/1530](https://github.com/spf13/cobra/pull/1530)
- Add Kubescape to projects -
[@&#8203;avinashupadhya99](https://github.com/avinashupadhya99)
[https://github.com/spf13/cobra/pull/1642](https://github.com/spf13/cobra/pull/1642)
- Add Pulumi as a project using cobra by
[@&#8203;iwahbe](https://github.com/iwahbe) in
[https://github.com/spf13/cobra/pull/1720](https://github.com/spf13/cobra/pull/1720)
- Add Polygon Edge as a project using Cobra by
[@&#8203;zivkovicmilos](https://github.com/zivkovicmilos) in
[https://github.com/spf13/cobra/pull/1672](https://github.com/spf13/cobra/pull/1672)

Shoutout to *ALL* our contributors (and all the new first time
contributors!!) - great work everyone!! Cobra and it's huge impact
wouldn't be possible without you 👏🏼 🚀 🐍

**Full Changelog**:
spf13/cobra@v1.4.0...v1.5.0

### [`v1.4.0`](https://github.com/spf13/cobra/releases/tag/v1.4.0)

[Compare
Source](https://github.com/spf13/cobra/compare/v1.3.0...v1.4.0)

### Winter 2022 Release ❄️

Another season, another release!

#### Goodbye viper! 🐍 🚀

The core Cobra library no longer requires Viper and all of its indirect
dependencies. This means that Cobra's dependency tree has been
drastically thinned! The Viper dependency was included because of the
`cobra` CLI generation tool. [This tool has migrated to
`spf13/cobra-cli`](https://github.com/spf13/cobra-cli/releases/tag/v1.3.0).

It's *pretty unlikely* you were importing and using **the bootstrapping
CLI tool** as part of your application (after all, it's just a tool to
get going with core `cobra`).

But if you were, replace occurrences of

    "github.com/spf13/cobra/cobra"

with

    "github.com/spf13/cobra-cli"

And in your `go.mod`, you'll want to also include this dependency:

    github.com/spf13/cobra-cli v1.3.0

Again, the maintainers *do not anticipate* this being a breaking change
to users of the core `cobra` library, so minimal work should be required
for users to integrate with this new release. Moreover, this means the
dependency tree for your application using Cobra should no longer
require dependencies that were inherited from Viper. Huzzah! 🥳

If you'd like to read more

- issue:
[https://github.com/spf13/cobra/issues/1597](https://github.com/spf13/cobra/issues/1597)
- PR:
[https://github.com/spf13/cobra/pull/1604](https://github.com/spf13/cobra/pull/1604)

#### Documentation 📝

- Update Go Doc link and badge in README:
[https://github.com/spf13/cobra/pull/1593](https://github.com/spf13/cobra/pull/1593)
- Fix to install command, now targets `@latest`:
[https://github.com/spf13/cobra/pull/1576](https://github.com/spf13/cobra/pull/1576)
- Added MAINTAINERS file:
[https://github.com/spf13/cobra/pull/1545](https://github.com/spf13/cobra/pull/1545)

#### Other 💭

- Bumped license year to 2022 in golden files:
[https://github.com/spf13/cobra/pull/1575](https://github.com/spf13/cobra/pull/1575)
- Added Pixie to projects:
[https://github.com/spf13/cobra/pull/1581](https://github.com/spf13/cobra/pull/1581)
- Updated labeler for new labeling scheme:
[https://github.com/spf13/cobra/pull/1613](https://github.com/spf13/cobra/pull/1613)
& syntax fix:
[https://github.com/spf13/cobra/pull/1624](https://github.com/spf13/cobra/pull/1624)

Shoutout to our awesome contributors helping to make this cobra release
possible!!
[@&#8203;spf13](https://github.com/spf13)
[@&#8203;marckhouzam](https://github.com/marckhouzam)
[@&#8203;johnSchnake](https://github.com/johnSchnake)
[@&#8203;jpmcb](https://github.com/jpmcb)
[@&#8203;liggitt](https://github.com/liggitt)
[@&#8203;umarcor](https://github.com/umarcor)
[@&#8203;hiljusti](https://github.com/hiljusti)
[@&#8203;marians](https://github.com/marians)
[@&#8203;shyim](https://github.com/shyim)
[@&#8203;htroisi](https://github.com/htroisi)

### [`v1.3.0`](https://github.com/spf13/cobra/releases/tag/v1.3.0)

[Compare
Source](https://github.com/spf13/cobra/compare/v1.2.1...v1.3.0)

### v1.3.0 - The Fall 2021 release 🍁

#### Completion fixes & enhancements 💇🏼

In `v1.2.0`, we introduced a new model for completions. Thanks to
everyone for trying it, giving feedback, and providing numerous fixes!
Continue to work with the new model as the old one (as noted in code
comments) will be deprecated in a coming release.

- `DisableFlagParsing` now triggers custom completions for flag names
[#&#8203;1161](https://github.com/spf13/cobra/issues/1161)
- Fixed unbound variables in bash completions causing edge case errors
[#&#8203;1321](https://github.com/spf13/cobra/issues/1321)
- `help` completion formatting improvements & fixes
[#&#8203;1444](https://github.com/spf13/cobra/issues/1444)
- All completions now follow the `help` example: short desc are now
capitalized and removes extra spacing from long description
[#&#8203;1455](https://github.com/spf13/cobra/issues/1455)
- Typo fixes in bash & zsh completions
[#&#8203;1459](https://github.com/spf13/cobra/issues/1459)
- Fixed mixed tab/spaces indentation in completion scripts. Now just 4
spaces [#&#8203;1473](https://github.com/spf13/cobra/issues/1473)
- Support for different bash completion options. Bash completions v2
supports descriptions and requires descriptions to be removed for
`menu-complete`, `menu-complete-backward` and `insert-completions`.
These descriptions are now purposefully removed in support of this
model. [#&#8203;1509](https://github.com/spf13/cobra/issues/1509)
- Fix for invalid shell completions when using `~/.cobra.yaml`. Log
message `Using config file: ~/.cobra.yaml` now printed to stderr
[#&#8203;1510](https://github.com/spf13/cobra/issues/1510)
- Removes unnecessary trailing spaces from completion command
descriptions
[#&#8203;1520](https://github.com/spf13/cobra/issues/1520)
- Option to hide default `completion` command
[#&#8203;1541](https://github.com/spf13/cobra/issues/1541)
- Remove `__complete` command for programs without subcommands
[#&#8203;1563](https://github.com/spf13/cobra/issues/1563)

#### Generator changes ⚙️

Thanks to [@&#8203;spf13](https://github.com/spf13) for providing a
number of changes to the Cobra generator tool, streamlining it for new
users!

- The Cobra generator now *won't* automatically include Viper and cleans
up a number of unused imports when not using Viper.
-   The Cobra generator's default license is now `none`
-   The Cobra generator now works with Go modules
-   Documentation to reflect these changes

#### New Features ⭐

- License can be specified by their SPDX identifiers
[#&#8203;1159](https://github.com/spf13/cobra/issues/1159)
- `MatchAll` allows combining several PositionalArgs to work in concert.
This now allows for enabling composing `PositionalArgs`
[#&#8203;896](https://github.com/spf13/cobra/issues/896)

#### Bug Fixes 🐛

- Fixed multiple error message from cobra `init` boilerplates
[#&#8203;1463](https://github.com/spf13/cobra/issues/1463)
[#&#8203;1552](https://github.com/spf13/cobra/issues/1552)
[#&#8203;1557](https://github.com/spf13/cobra/issues/1557)

#### Testing 👀

- Now testing golang 1.16.x and 1.17.x in CI
[#&#8203;1425](https://github.com/spf13/cobra/issues/1425)
- Fix for running diff test to ignore CR for windows
[#&#8203;949](https://github.com/spf13/cobra/issues/949)
- Added helper functions and reduced code reproduction in `args_test`
[#&#8203;1426](https://github.com/spf13/cobra/issues/1426)
- Now using official `golangci-lint` github action
[#&#8203;1477](https://github.com/spf13/cobra/issues/1477)

#### Security 🔏

- Added GitHub dependabot
[#&#8203;1427](https://github.com/spf13/cobra/issues/1427)
-   Now using Viper `v1.10.0`
- There is a known CVE in an *indirect* dependency from `viper`:
[https://github.com/spf13/cobra/issues/1538](https://github.com/spf13/cobra/issues/1538).
This will be patched in a future release

#### Documentation 📝

- Multiple projects added to the `projects_using_cobra.md` file:
[#&#8203;1377](https://github.com/spf13/cobra/issues/1377)
[#&#8203;1501](https://github.com/spf13/cobra/issues/1501)
[#&#8203;1454](https://github.com/spf13/cobra/issues/1454)
- Removed ToC from main readme file as it is now automagically displayed
by GitHub [#&#8203;1429](https://github.com/spf13/cobra/issues/1429)
- Documentation correct for when the `--author` flag is specified
[#&#8203;1009](https://github.com/spf13/cobra/issues/1009)
- `shell_completions.md` has an easier to use snippet for copying and
pasting shell completions
[#&#8203;1372](https://github.com/spf13/cobra/issues/1372)

#### Other 💭

- Bump version of `cpuguy83/go-md2man` to v2.0.1
[#&#8203;1460](https://github.com/spf13/cobra/issues/1460)
- Removed `lesser` typo from the GPL-2.0 license
[#&#8203;880](https://github.com/spf13/cobra/issues/880)
- Fixed spelling errors
[#&#8203;1514](https://github.com/spf13/cobra/issues/1514)

*Thank you to all our amazing contributors* ⭐🐍🚀

### [`v1.2.1`](https://github.com/spf13/cobra/releases/tag/v1.2.1)

[Compare
Source](https://github.com/spf13/cobra/compare/v1.2.0...v1.2.1)

##### Bug fixes

- Quickfix for
[https://github.com/spf13/cobra/issues/1437](https://github.com/spf13/cobra/issues/1437)
after v1.2.0 where parallel use of the
`cmd.RegisterFlagCompletionFunc()` (and subsequent map) now works
correctly and flag completions now work again

### [`v1.2.0`](https://github.com/spf13/cobra/releases/tag/v1.2.0): -
The completions release

[Compare
Source](https://github.com/spf13/cobra/compare/v1.1.3...v1.2.0)

### 🌠 v1.2.0 - The completions release

Welcome to v1.2.0 of Cobra! This release focuses on code completions,
several critical bug fixes, some documentation updates, and security
bumps. Upgrading should be simple but please take note of the
introduction of bash completions V2 and their default use. The v1
completions library is still available, but will be *deprecated* in the
future. Please open an issue with any problems!

***

#### New Features

- Automatically adds a `completion` command for shell completions. If a
`completion` command is already provided, uses that instead. This will
*automatically* provide shell completions for bash, zsh, fish, and
PowerShell
[https://github.com/spf13/cobra/pull/1192](https://github.com/spf13/cobra/pull/1192)
    -   Users can configure the command auto creation:
        -   disable the creation of the completion command
        -   disable completion descriptions
- disable the `--no-descriptions` flag for "always on" completion
descriptions
- Introduction of bash completions V2, a uniform completion approach
which include completion descriptions. The V1 bash completions are still
available *but will be deprecated* in a later release -
[https://github.com/spf13/cobra/pull/1146](https://github.com/spf13/cobra/pull/1146)
- Note that projects providing completion through a different command
name (say a command named "complete") will continue to use v1 for their
own command but will also provide cobra's implicit "completion" command
which will use v2, unless of course, these projects take the time to
disable the default "completion" command as noted above.
- Commands now support context being passed to completions -
[https://github.com/spf13/cobra/pull/1265](https://github.com/spf13/cobra/pull/1265)
- An example can be found here:
[https://github.com/spf13/cobra/pull/1265#issuecomment-734551031](https://github.com/spf13/cobra/pull/1265#issuecomment-734551031)
- Removed dependency on`mitchellh/go-homedir` in favor of core Go
`os.UserHomeDir()` -
spf13/cobra@8eaca5f

#### Bug Fixes

- Fix trailing whitespace not being handled in powershell completion
scripts
[https://github.com/spf13/cobra/pull/1342](https://github.com/spf13/cobra/pull/1342)
- Bash completion variable leak fix
[https://github.com/spf13/cobra/pull/1352](https://github.com/spf13/cobra/pull/1352)
- Fish shell completions correctly ignore trailing empty lines
[https://github.com/spf13/cobra/pull/1284](https://github.com/spf13/cobra/pull/1284)
- PowerShell completions fix for "no file comp directive" -
[https://github.com/spf13/cobra/pull/1363](https://github.com/spf13/cobra/pull/1363)
- Custom completions now correctly handle multiple shorthand flags
together -
[https://github.com/spf13/cobra/pull/1258](https://github.com/spf13/cobra/pull/1258)
- zsh completions now correctly handle `ShellDirectiveCompletionNoSpace`
and file completion all the time -
[https://github.com/spf13/cobra/pull/1213](https://github.com/spf13/cobra/pull/1213)
- Multiple fixes / improvements to the fish shell support -
[https://github.com/spf13/cobra/pull/1249](https://github.com/spf13/cobra/pull/1249)
- Fix home directory config not loading correctly -
[https://github.com/spf13/cobra/pull/1282](https://github.com/spf13/cobra/pull/1282)
- Fix for `RegisterFlagCompletionFunc` as a global var not working in
multi-threaded programs:
[https://github.com/spf13/cobra/pull/1423](https://github.com/spf13/cobra/pull/1423)
- Custom completions correctly do not complete flags after args when
interspersed is false
[#&#8203;1308](https://github.com/spf13/cobra/issues/1308)

#### Testing

- Deprecated Travis CI. Now fully using Github Actions -
spf13/cobra@d0f318d
- Added test cases and enhancements (thank you to everyone for taking
the time to add tests to your PRs!)
- Shoutout to [@&#8203;marckhouzam](https://github.com/marckhouzam)
and [@&#8203;Luap99](https://github.com/Luap99) for their hard work on
a cobra command completions testing library. [Check out the repo
here!](https://github.com/marckhouzam/cobra-completion-testing)

#### Security

- Bump viper to 1.8.1. This corrects several issues with vulnerabilities
existing in the dependency tree -
[https://github.com/spf13/cobra/pull/1433](https://github.com/spf13/cobra/pull/1433)

#### Other

- Add PR labeler with pull_request_target to enable tests to run from
forks -
[https://github.com/spf13/cobra/pull/1338](https://github.com/spf13/cobra/pull/1338)
- CI using MSYS2 windows machines pull latest -
[https://github.com/spf13/cobra/pull/1366](https://github.com/spf13/cobra/pull/1366)
- Multiple small fixes to spelling / documentation -
[https://github.com/spf13/cobra/pull/1349](https://github.com/spf13/cobra/pull/1349)
[https://github.com/spf13/cobra/pull/1417](https://github.com/spf13/cobra/pull/1417)
[https://github.com/spf13/cobra/pull/1434](https://github.com/spf13/cobra/pull/1434)

**Thank you to *all* our amazing contributors 🐍🚀**

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/PingCAP-QE/ee-apps).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy44Ny4yIiwidXBkYXRlZEluVmVyIjoiMzcuODcuMiIsInRhcmdldEJyYW5jaCI6Im1haW4ifQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants