1# Generating shell completions 2 3Cobra can generate shell completions for multiple shells. 4The currently supported shells are: 5- Bash 6- Zsh 7- fish 8- PowerShell 9 10If you are using the generator, you can create a completion command by running 11 12```bash 13cobra add completion 14``` 15and then modifying the generated `cmd/completion.go` file to look something like this 16(writing the shell script to stdout allows the most flexible use): 17 18```go 19var completionCmd = &cobra.Command{ 20 Use: "completion [bash|zsh|fish|powershell]", 21 Short: "Generate completion script", 22 Long: `To load completions: 23 24Bash: 25 26 $ source <(yourprogram completion bash) 27 28 # To load completions for each session, execute once: 29 # Linux: 30 $ yourprogram completion bash > /etc/bash_completion.d/yourprogram 31 # macOS: 32 $ yourprogram completion bash > /usr/local/etc/bash_completion.d/yourprogram 33 34Zsh: 35 36 # If shell completion is not already enabled in your environment, 37 # you will need to enable it. You can execute the following once: 38 39 $ echo "autoload -U compinit; compinit" >> ~/.zshrc 40 41 # To load completions for each session, execute once: 42 $ yourprogram completion zsh > "${fpath[1]}/_yourprogram" 43 44 # You will need to start a new shell for this setup to take effect. 45 46fish: 47 48 $ yourprogram completion fish | source 49 50 # To load completions for each session, execute once: 51 $ yourprogram completion fish > ~/.config/fish/completions/yourprogram.fish 52 53PowerShell: 54 55 PS> yourprogram completion powershell | Out-String | Invoke-Expression 56 57 # To load completions for every new session, run: 58 PS> yourprogram completion powershell > yourprogram.ps1 59 # and source this file from your PowerShell profile. 60`, 61 DisableFlagsInUseLine: true, 62 ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, 63 Args: cobra.ExactValidArgs(1), 64 Run: func(cmd *cobra.Command, args []string) { 65 switch args[0] { 66 case "bash": 67 cmd.Root().GenBashCompletion(os.Stdout) 68 case "zsh": 69 cmd.Root().GenZshCompletion(os.Stdout) 70 case "fish": 71 cmd.Root().GenFishCompletion(os.Stdout, true) 72 case "powershell": 73 cmd.Root().GenPowerShellCompletion(os.Stdout) 74 } 75 }, 76} 77``` 78 79**Note:** The cobra generator may include messages printed to stdout, for example, if the config file is loaded; this will break the auto-completion script so must be removed. 80 81# Customizing completions 82 83The generated completion scripts will automatically handle completing commands and flags. However, you can make your completions much more powerful by providing information to complete your program's nouns and flag values. 84 85## Completion of nouns 86 87### Static completion of nouns 88 89Cobra allows you to provide a pre-defined list of completion choices for your nouns using the `ValidArgs` field. 90For example, if you want `kubectl get [tab][tab]` to show a list of valid "nouns" you have to set them. 91Some simplified code from `kubectl get` looks like: 92 93```go 94validArgs []string = { "pod", "node", "service", "replicationcontroller" } 95 96cmd := &cobra.Command{ 97 Use: "get [(-o|--output=)json|yaml|template|...] (RESOURCE [NAME] | RESOURCE/NAME ...)", 98 Short: "Display one or many resources", 99 Long: get_long, 100 Example: get_example, 101 Run: func(cmd *cobra.Command, args []string) { 102 cobra.CheckErr(RunGet(f, out, cmd, args)) 103 }, 104 ValidArgs: validArgs, 105} 106``` 107 108Notice we put the `ValidArgs` field on the `get` sub-command. Doing so will give results like: 109 110```bash 111$ kubectl get [tab][tab] 112node pod replicationcontroller service 113``` 114 115#### Aliases for nouns 116 117If your nouns have aliases, you can define them alongside `ValidArgs` using `ArgAliases`: 118 119```go 120argAliases []string = { "pods", "nodes", "services", "svc", "replicationcontrollers", "rc" } 121 122cmd := &cobra.Command{ 123 ... 124 ValidArgs: validArgs, 125 ArgAliases: argAliases 126} 127``` 128 129The aliases are not shown to the user on tab completion, but they are accepted as valid nouns by 130the completion algorithm if entered manually, e.g. in: 131 132```bash 133$ kubectl get rc [tab][tab] 134backend frontend database 135``` 136 137Note that without declaring `rc` as an alias, the completion algorithm would not know to show the list of 138replication controllers following `rc`. 139 140### Dynamic completion of nouns 141 142In some cases it is not possible to provide a list of completions in advance. Instead, the list of completions must be determined at execution-time. In a similar fashion as for static completions, you can use the `ValidArgsFunction` field to provide a Go function that Cobra will execute when it needs the list of completion choices for the nouns of a command. Note that either `ValidArgs` or `ValidArgsFunction` can be used for a single cobra command, but not both. 143Simplified code from `helm status` looks like: 144 145```go 146cmd := &cobra.Command{ 147 Use: "status RELEASE_NAME", 148 Short: "Display the status of the named release", 149 Long: status_long, 150 RunE: func(cmd *cobra.Command, args []string) { 151 RunGet(args[0]) 152 }, 153 ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { 154 if len(args) != 0 { 155 return nil, cobra.ShellCompDirectiveNoFileComp 156 } 157 return getReleasesFromCluster(toComplete), cobra.ShellCompDirectiveNoFileComp 158 }, 159} 160``` 161Where `getReleasesFromCluster()` is a Go function that obtains the list of current Helm releases running on the Kubernetes cluster. 162Notice we put the `ValidArgsFunction` on the `status` sub-command. Let's assume the Helm releases on the cluster are: `harbor`, `notary`, `rook` and `thanos` then this dynamic completion will give results like: 163 164```bash 165$ helm status [tab][tab] 166harbor notary rook thanos 167``` 168You may have noticed the use of `cobra.ShellCompDirective`. These directives are bit fields allowing to control some shell completion behaviors for your particular completion. You can combine them with the bit-or operator such as `cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp` 169```go 170// Indicates that the shell will perform its default behavior after completions 171// have been provided (this implies none of the other directives). 172ShellCompDirectiveDefault 173 174// Indicates an error occurred and completions should be ignored. 175ShellCompDirectiveError 176 177// Indicates that the shell should not add a space after the completion, 178// even if there is a single completion provided. 179ShellCompDirectiveNoSpace 180 181// Indicates that the shell should not provide file completion even when 182// no completion is provided. 183ShellCompDirectiveNoFileComp 184 185// Indicates that the returned completions should be used as file extension filters. 186// For example, to complete only files of the form *.json or *.yaml: 187// return []string{"yaml", "json"}, ShellCompDirectiveFilterFileExt 188// For flags, using MarkFlagFilename() and MarkPersistentFlagFilename() 189// is a shortcut to using this directive explicitly. 190// 191ShellCompDirectiveFilterFileExt 192 193// Indicates that only directory names should be provided in file completion. 194// For example: 195// return nil, ShellCompDirectiveFilterDirs 196// For flags, using MarkFlagDirname() is a shortcut to using this directive explicitly. 197// 198// To request directory names within another directory, the returned completions 199// should specify a single directory name within which to search. For example, 200// to complete directories within "themes/": 201// return []string{"themes"}, ShellCompDirectiveFilterDirs 202// 203ShellCompDirectiveFilterDirs 204``` 205 206***Note***: When using the `ValidArgsFunction`, Cobra will call your registered function after having parsed all flags and arguments provided in the command-line. You therefore don't need to do this parsing yourself. For example, when a user calls `helm status --namespace my-rook-ns [tab][tab]`, Cobra will call your registered `ValidArgsFunction` after having parsed the `--namespace` flag, as it would have done when calling the `RunE` function. 207 208#### Debugging 209 210Cobra achieves dynamic completion through the use of a hidden command called by the completion script. To debug your Go completion code, you can call this hidden command directly: 211```bash 212$ helm __complete status har<ENTER> 213harbor 214:4 215Completion ended with directive: ShellCompDirectiveNoFileComp # This is on stderr 216``` 217***Important:*** If the noun to complete is empty (when the user has not yet typed any letters of that noun), you must pass an empty parameter to the `__complete` command: 218```bash 219$ helm __complete status ""<ENTER> 220harbor 221notary 222rook 223thanos 224:4 225Completion ended with directive: ShellCompDirectiveNoFileComp # This is on stderr 226``` 227Calling the `__complete` command directly allows you to run the Go debugger to troubleshoot your code. You can also add printouts to your code; Cobra provides the following functions to use for printouts in Go completion code: 228```go 229// Prints to the completion script debug file (if BASH_COMP_DEBUG_FILE 230// is set to a file path) and optionally prints to stderr. 231cobra.CompDebug(msg string, printToStdErr bool) { 232cobra.CompDebugln(msg string, printToStdErr bool) 233 234// Prints to the completion script debug file (if BASH_COMP_DEBUG_FILE 235// is set to a file path) and to stderr. 236cobra.CompError(msg string) 237cobra.CompErrorln(msg string) 238``` 239***Important:*** You should **not** leave traces that print directly to stdout in your completion code as they will be interpreted as completion choices by the completion script. Instead, use the cobra-provided debugging traces functions mentioned above. 240 241## Completions for flags 242 243### Mark flags as required 244 245Most of the time completions will only show sub-commands. But if a flag is required to make a sub-command work, you probably want it to show up when the user types [tab][tab]. You can mark a flag as 'Required' like so: 246 247```go 248cmd.MarkFlagRequired("pod") 249cmd.MarkFlagRequired("container") 250``` 251 252and you'll get something like 253 254```bash 255$ kubectl exec [tab][tab] 256-c --container= -p --pod= 257``` 258 259### Specify dynamic flag completion 260 261As for nouns, Cobra provides a way of defining dynamic completion of flags. To provide a Go function that Cobra will execute when it needs the list of completion choices for a flag, you must register the function using the `command.RegisterFlagCompletionFunc()` function. 262 263```go 264flagName := "output" 265cmd.RegisterFlagCompletionFunc(flagName, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { 266 return []string{"json", "table", "yaml"}, cobra.ShellCompDirectiveDefault 267}) 268``` 269Notice that calling `RegisterFlagCompletionFunc()` is done through the `command` with which the flag is associated. In our example this dynamic completion will give results like so: 270 271```bash 272$ helm status --output [tab][tab] 273json table yaml 274``` 275 276#### Debugging 277 278You can also easily debug your Go completion code for flags: 279```bash 280$ helm __complete status --output "" 281json 282table 283yaml 284:4 285Completion ended with directive: ShellCompDirectiveNoFileComp # This is on stderr 286``` 287***Important:*** You should **not** leave traces that print to stdout in your completion code as they will be interpreted as completion choices by the completion script. Instead, use the cobra-provided debugging traces functions mentioned further above. 288 289### Specify valid filename extensions for flags that take a filename 290 291To limit completions of flag values to file names with certain extensions you can either use the different `MarkFlagFilename()` functions or a combination of `RegisterFlagCompletionFunc()` and `ShellCompDirectiveFilterFileExt`, like so: 292```go 293flagName := "output" 294cmd.MarkFlagFilename(flagName, "yaml", "json") 295``` 296or 297```go 298flagName := "output" 299cmd.RegisterFlagCompletionFunc(flagName, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { 300 return []string{"yaml", "json"}, ShellCompDirectiveFilterFileExt}) 301``` 302 303### Limit flag completions to directory names 304 305To limit completions of flag values to directory names you can either use the `MarkFlagDirname()` functions or a combination of `RegisterFlagCompletionFunc()` and `ShellCompDirectiveFilterDirs`, like so: 306```go 307flagName := "output" 308cmd.MarkFlagDirname(flagName) 309``` 310or 311```go 312flagName := "output" 313cmd.RegisterFlagCompletionFunc(flagName, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { 314 return nil, cobra.ShellCompDirectiveFilterDirs 315}) 316``` 317To limit completions of flag values to directory names *within another directory* you can use a combination of `RegisterFlagCompletionFunc()` and `ShellCompDirectiveFilterDirs` like so: 318```go 319flagName := "output" 320cmd.RegisterFlagCompletionFunc(flagName, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { 321 return []string{"themes"}, cobra.ShellCompDirectiveFilterDirs 322}) 323``` 324### Descriptions for completions 325 326`zsh`, `fish` and `powershell` allow for descriptions to annotate completion choices. For commands and flags, Cobra will provide the descriptions automatically, based on usage information. For example, using zsh: 327``` 328$ helm s[tab] 329search -- search for a keyword in charts 330show -- show information of a chart 331status -- displays the status of the named release 332``` 333while using fish: 334``` 335$ helm s[tab] 336search (search for a keyword in charts) show (show information of a chart) status (displays the status of the named release) 337``` 338 339Cobra allows you to add annotations to your own completions. Simply add the annotation text after each completion, following a `\t` separator. This technique applies to completions returned by `ValidArgs`, `ValidArgsFunction` and `RegisterFlagCompletionFunc()`. For example: 340```go 341ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { 342 return []string{"harbor\tAn image registry", "thanos\tLong-term metrics"}, cobra.ShellCompDirectiveNoFileComp 343}} 344``` 345or 346```go 347ValidArgs: []string{"bash\tCompletions for bash", "zsh\tCompletions for zsh"} 348``` 349## Bash completions 350 351### Dependencies 352 353The bash completion script generated by Cobra requires the `bash_completion` package. You should update the help text of your completion command to show how to install the `bash_completion` package ([Kubectl docs](https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion)) 354 355### Aliases 356 357You can also configure `bash` aliases for your program and they will also support completions. 358 359```bash 360alias aliasname=origcommand 361complete -o default -F __start_origcommand aliasname 362 363# and now when you run `aliasname` completion will make 364# suggestions as it did for `origcommand`. 365 366$ aliasname <tab><tab> 367completion firstcommand secondcommand 368``` 369### Bash legacy dynamic completions 370 371For backward compatibility, Cobra still supports its bash legacy dynamic completion solution. 372Please refer to [Bash Completions](bash_completions.md) for details. 373 374## Zsh completions 375 376Cobra supports native zsh completion generated from the root `cobra.Command`. 377The generated completion script should be put somewhere in your `$fpath` and be named 378`_<yourProgram>`. You will need to start a new shell for the completions to become available. 379 380Zsh supports descriptions for completions. Cobra will provide the description automatically, 381based on usage information. Cobra provides a way to completely disable such descriptions by 382using `GenZshCompletionNoDesc()` or `GenZshCompletionFileNoDesc()`. You can choose to make 383this a configurable option to your users. 384``` 385# With descriptions 386$ helm s[tab] 387search -- search for a keyword in charts 388show -- show information of a chart 389status -- displays the status of the named release 390 391# Without descriptions 392$ helm s[tab] 393search show status 394``` 395*Note*: Because of backward-compatibility requirements, we were forced to have a different API to disable completion descriptions between `zsh` and `fish`. 396 397### Limitations 398 399* Custom completions implemented in Bash scripting (legacy) are not supported and will be ignored for `zsh` (including the use of the `BashCompCustom` flag annotation). 400 * You should instead use `ValidArgsFunction` and `RegisterFlagCompletionFunc()` which are portable to the different shells (`bash`, `zsh`, `fish`, `powershell`). 401* The function `MarkFlagCustom()` is not supported and will be ignored for `zsh`. 402 * You should instead use `RegisterFlagCompletionFunc()`. 403 404### Zsh completions standardization 405 406Cobra 1.1 standardized its zsh completion support to align it with its other shell completions. Although the API was kept backward-compatible, some small changes in behavior were introduced. 407Please refer to [Zsh Completions](zsh_completions.md) for details. 408 409## fish completions 410 411Cobra supports native fish completions generated from the root `cobra.Command`. You can use the `command.GenFishCompletion()` or `command.GenFishCompletionFile()` functions. You must provide these functions with a parameter indicating if the completions should be annotated with a description; Cobra will provide the description automatically based on usage information. You can choose to make this option configurable by your users. 412``` 413# With descriptions 414$ helm s[tab] 415search (search for a keyword in charts) show (show information of a chart) status (displays the status of the named release) 416 417# Without descriptions 418$ helm s[tab] 419search show status 420``` 421*Note*: Because of backward-compatibility requirements, we were forced to have a different API to disable completion descriptions between `zsh` and `fish`. 422 423### Limitations 424 425* Custom completions implemented in bash scripting (legacy) are not supported and will be ignored for `fish` (including the use of the `BashCompCustom` flag annotation). 426 * You should instead use `ValidArgsFunction` and `RegisterFlagCompletionFunc()` which are portable to the different shells (`bash`, `zsh`, `fish`, `powershell`). 427* The function `MarkFlagCustom()` is not supported and will be ignored for `fish`. 428 * You should instead use `RegisterFlagCompletionFunc()`. 429* The following flag completion annotations are not supported and will be ignored for `fish`: 430 * `BashCompFilenameExt` (filtering by file extension) 431 * `BashCompSubdirsInDir` (filtering by directory) 432* The functions corresponding to the above annotations are consequently not supported and will be ignored for `fish`: 433 * `MarkFlagFilename()` and `MarkPersistentFlagFilename()` (filtering by file extension) 434 * `MarkFlagDirname()` and `MarkPersistentFlagDirname()` (filtering by directory) 435* Similarly, the following completion directives are not supported and will be ignored for `fish`: 436 * `ShellCompDirectiveFilterFileExt` (filtering by file extension) 437 * `ShellCompDirectiveFilterDirs` (filtering by directory) 438 439## PowerShell completions 440 441Cobra supports native PowerShell completions generated from the root `cobra.Command`. You can use the `command.GenPowerShellCompletion()` or `command.GenPowerShellCompletionFile()` functions. To include descriptions use `command.GenPowerShellCompletionWithDesc()` and `command.GenPowerShellCompletionFileWithDesc()`. Cobra will provide the description automatically based on usage information. You can choose to make this option configurable by your users. 442 443The script is designed to support all three PowerShell completion modes: 444 445* TabCompleteNext (default windows style - on each key press the next option is displayed) 446* Complete (works like bash) 447* MenuComplete (works like zsh) 448 449You set the mode with `Set-PSReadLineKeyHandler -Key Tab -Function <mode>`. Descriptions are only displayed when using the `Complete` or `MenuComplete` mode. 450 451Users need PowerShell version 5.0 or above, which comes with Windows 10 and can be downloaded separately for Windows 7 or 8.1. They can then write the completions to a file and source this file from their PowerShell profile, which is referenced by the `$Profile` environment variable. See `Get-Help about_Profiles` for more info about PowerShell profiles. 452 453``` 454# With descriptions and Mode 'Complete' 455$ helm s[tab] 456search (search for a keyword in charts) show (show information of a chart) status (displays the status of the named release) 457 458# With descriptions and Mode 'MenuComplete' The description of the current selected value will be displayed below the suggestions. 459$ helm s[tab] 460search show status 461 462search for a keyword in charts 463 464# Without descriptions 465$ helm s[tab] 466search show status 467``` 468 469### Limitations 470 471* Custom completions implemented in bash scripting (legacy) are not supported and will be ignored for `powershell` (including the use of the `BashCompCustom` flag annotation). 472 * You should instead use `ValidArgsFunction` and `RegisterFlagCompletionFunc()` which are portable to the different shells (`bash`, `zsh`, `fish`, `powershell`). 473* The function `MarkFlagCustom()` is not supported and will be ignored for `powershell`. 474 * You should instead use `RegisterFlagCompletionFunc()`. 475* The following flag completion annotations are not supported and will be ignored for `powershell`: 476 * `BashCompFilenameExt` (filtering by file extension) 477 * `BashCompSubdirsInDir` (filtering by directory) 478* The functions corresponding to the above annotations are consequently not supported and will be ignored for `powershell`: 479 * `MarkFlagFilename()` and `MarkPersistentFlagFilename()` (filtering by file extension) 480 * `MarkFlagDirname()` and `MarkPersistentFlagDirname()` (filtering by directory) 481* Similarly, the following completion directives are not supported and will be ignored for `powershell`: 482 * `ShellCompDirectiveFilterFileExt` (filtering by file extension) 483 * `ShellCompDirectiveFilterDirs` (filtering by directory) 484