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
10Cobra will automatically provide your program with a fully functional `completion` command,
11similarly to how it provides the `help` command.
12
13## Creating your own completion command
14
15If you do not wish to use the default `completion` command, you can choose to
16provide your own, which will take precedence over the default one. (This also provides
17backwards-compatibility with programs that already have their own `completion` command.)
18
19If you are using the generator, you can create a completion command by running
20
21```bash
22cobra add completion
23```
24and then modifying the generated `cmd/completion.go` file to look something like this
25(writing the shell script to stdout allows the most flexible use):
26
27```go
28var completionCmd = &cobra.Command{
29	Use:   "completion [bash|zsh|fish|powershell]",
30	Short: "Generate completion script",
31	Long: `To load completions:
32
33Bash:
34
35  $ source <(yourprogram completion bash)
36
37  # To load completions for each session, execute once:
38  # Linux:
39  $ yourprogram completion bash > /etc/bash_completion.d/yourprogram
40  # macOS:
41  $ yourprogram completion bash > /usr/local/etc/bash_completion.d/yourprogram
42
43Zsh:
44
45  # If shell completion is not already enabled in your environment,
46  # you will need to enable it.  You can execute the following once:
47
48  $ echo "autoload -U compinit; compinit" >> ~/.zshrc
49
50  # To load completions for each session, execute once:
51  $ yourprogram completion zsh > "${fpath[1]}/_yourprogram"
52
53  # You will need to start a new shell for this setup to take effect.
54
55fish:
56
57  $ yourprogram completion fish | source
58
59  # To load completions for each session, execute once:
60  $ yourprogram completion fish > ~/.config/fish/completions/yourprogram.fish
61
62PowerShell:
63
64  PS> yourprogram completion powershell | Out-String | Invoke-Expression
65
66  # To load completions for every new session, run:
67  PS> yourprogram completion powershell > yourprogram.ps1
68  # and source this file from your PowerShell profile.
69`,
70	DisableFlagsInUseLine: true,
71	ValidArgs:             []string{"bash", "zsh", "fish", "powershell"},
72	Args:                  cobra.ExactValidArgs(1),
73	Run: func(cmd *cobra.Command, args []string) {
74		switch args[0] {
75		case "bash":
76			cmd.Root().GenBashCompletion(os.Stdout)
77		case "zsh":
78			cmd.Root().GenZshCompletion(os.Stdout)
79		case "fish":
80			cmd.Root().GenFishCompletion(os.Stdout, true)
81		case "powershell":
82			cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
83		}
84	},
85}
86```
87
88**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.
89
90## Adapting the default completion command
91
92Cobra provides a few options for the default `completion` command.  To configure such options you must set
93the `CompletionOptions` field on the *root* command.
94
95To tell Cobra *not* to provide the default `completion` command:
96```
97rootCmd.CompletionOptions.DisableDefaultCmd = true
98```
99
100To tell Cobra *not* to provide the user with the `--no-descriptions` flag to the completion sub-commands:
101```
102rootCmd.CompletionOptions.DisableNoDescFlag = true
103```
104
105To tell Cobra to completely disable descriptions for completions:
106```
107rootCmd.CompletionOptions.DisableDescriptions = true
108```
109
110# Customizing completions
111
112The 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.
113
114## Completion of nouns
115
116### Static completion of nouns
117
118Cobra allows you to provide a pre-defined list of completion choices for your nouns using the `ValidArgs` field.
119For example, if you want `kubectl get [tab][tab]` to show a list of valid "nouns" you have to set them.
120Some simplified code from `kubectl get` looks like:
121
122```go
123validArgs []string = { "pod", "node", "service", "replicationcontroller" }
124
125cmd := &cobra.Command{
126	Use:     "get [(-o|--output=)json|yaml|template|...] (RESOURCE [NAME] | RESOURCE/NAME ...)",
127	Short:   "Display one or many resources",
128	Long:    get_long,
129	Example: get_example,
130	Run: func(cmd *cobra.Command, args []string) {
131		cobra.CheckErr(RunGet(f, out, cmd, args))
132	},
133	ValidArgs: validArgs,
134}
135```
136
137Notice we put the `ValidArgs` field on the `get` sub-command. Doing so will give results like:
138
139```bash
140$ kubectl get [tab][tab]
141node   pod   replicationcontroller   service
142```
143
144#### Aliases for nouns
145
146If your nouns have aliases, you can define them alongside `ValidArgs` using `ArgAliases`:
147
148```go
149argAliases []string = { "pods", "nodes", "services", "svc", "replicationcontrollers", "rc" }
150
151cmd := &cobra.Command{
152    ...
153	ValidArgs:  validArgs,
154	ArgAliases: argAliases
155}
156```
157
158The aliases are not shown to the user on tab completion, but they are accepted as valid nouns by
159the completion algorithm if entered manually, e.g. in:
160
161```bash
162$ kubectl get rc [tab][tab]
163backend        frontend       database
164```
165
166Note that without declaring `rc` as an alias, the completion algorithm would not know to show the list of
167replication controllers following `rc`.
168
169### Dynamic completion of nouns
170
171In 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.
172Simplified code from `helm status` looks like:
173
174```go
175cmd := &cobra.Command{
176	Use:   "status RELEASE_NAME",
177	Short: "Display the status of the named release",
178	Long:  status_long,
179	RunE: func(cmd *cobra.Command, args []string) {
180		RunGet(args[0])
181	},
182	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
183		if len(args) != 0 {
184			return nil, cobra.ShellCompDirectiveNoFileComp
185		}
186		return getReleasesFromCluster(toComplete), cobra.ShellCompDirectiveNoFileComp
187	},
188}
189```
190Where `getReleasesFromCluster()` is a Go function that obtains the list of current Helm releases running on the Kubernetes cluster.
191Notice 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:
192
193```bash
194$ helm status [tab][tab]
195harbor notary rook thanos
196```
197You 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`
198```go
199// Indicates that the shell will perform its default behavior after completions
200// have been provided (this implies none of the other directives).
201ShellCompDirectiveDefault
202
203// Indicates an error occurred and completions should be ignored.
204ShellCompDirectiveError
205
206// Indicates that the shell should not add a space after the completion,
207// even if there is a single completion provided.
208ShellCompDirectiveNoSpace
209
210// Indicates that the shell should not provide file completion even when
211// no completion is provided.
212ShellCompDirectiveNoFileComp
213
214// Indicates that the returned completions should be used as file extension filters.
215// For example, to complete only files of the form *.json or *.yaml:
216//    return []string{"yaml", "json"}, ShellCompDirectiveFilterFileExt
217// For flags, using MarkFlagFilename() and MarkPersistentFlagFilename()
218// is a shortcut to using this directive explicitly.
219//
220ShellCompDirectiveFilterFileExt
221
222// Indicates that only directory names should be provided in file completion.
223// For example:
224//    return nil, ShellCompDirectiveFilterDirs
225// For flags, using MarkFlagDirname() is a shortcut to using this directive explicitly.
226//
227// To request directory names within another directory, the returned completions
228// should specify a single directory name within which to search. For example,
229// to complete directories within "themes/":
230//    return []string{"themes"}, ShellCompDirectiveFilterDirs
231//
232ShellCompDirectiveFilterDirs
233```
234
235***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.
236
237#### Debugging
238
239Cobra 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:
240```bash
241$ helm __complete status har<ENTER>
242harbor
243:4
244Completion ended with directive: ShellCompDirectiveNoFileComp # This is on stderr
245```
246***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:
247```bash
248$ helm __complete status ""<ENTER>
249harbor
250notary
251rook
252thanos
253:4
254Completion ended with directive: ShellCompDirectiveNoFileComp # This is on stderr
255```
256Calling 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:
257```go
258// Prints to the completion script debug file (if BASH_COMP_DEBUG_FILE
259// is set to a file path) and optionally prints to stderr.
260cobra.CompDebug(msg string, printToStdErr bool) {
261cobra.CompDebugln(msg string, printToStdErr bool)
262
263// Prints to the completion script debug file (if BASH_COMP_DEBUG_FILE
264// is set to a file path) and to stderr.
265cobra.CompError(msg string)
266cobra.CompErrorln(msg string)
267```
268***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.
269
270## Completions for flags
271
272### Mark flags as required
273
274Most 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:
275
276```go
277cmd.MarkFlagRequired("pod")
278cmd.MarkFlagRequired("container")
279```
280
281and you'll get something like
282
283```bash
284$ kubectl exec [tab][tab]
285-c            --container=  -p            --pod=
286```
287
288### Specify dynamic flag completion
289
290As 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.
291
292```go
293flagName := "output"
294cmd.RegisterFlagCompletionFunc(flagName, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
295	return []string{"json", "table", "yaml"}, cobra.ShellCompDirectiveDefault
296})
297```
298Notice 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:
299
300```bash
301$ helm status --output [tab][tab]
302json table yaml
303```
304
305#### Debugging
306
307You can also easily debug your Go completion code for flags:
308```bash
309$ helm __complete status --output ""
310json
311table
312yaml
313:4
314Completion ended with directive: ShellCompDirectiveNoFileComp # This is on stderr
315```
316***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.
317
318### Specify valid filename extensions for flags that take a filename
319
320To 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:
321```go
322flagName := "output"
323cmd.MarkFlagFilename(flagName, "yaml", "json")
324```
325or
326```go
327flagName := "output"
328cmd.RegisterFlagCompletionFunc(flagName, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
329	return []string{"yaml", "json"}, ShellCompDirectiveFilterFileExt})
330```
331
332### Limit flag completions to directory names
333
334To limit completions of flag values to directory names you can either use the `MarkFlagDirname()` functions or a combination of `RegisterFlagCompletionFunc()` and `ShellCompDirectiveFilterDirs`, like so:
335```go
336flagName := "output"
337cmd.MarkFlagDirname(flagName)
338```
339or
340```go
341flagName := "output"
342cmd.RegisterFlagCompletionFunc(flagName, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
343	return nil, cobra.ShellCompDirectiveFilterDirs
344})
345```
346To limit completions of flag values to directory names *within another directory* you can use a combination of `RegisterFlagCompletionFunc()` and `ShellCompDirectiveFilterDirs` like so:
347```go
348flagName := "output"
349cmd.RegisterFlagCompletionFunc(flagName, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
350	return []string{"themes"}, cobra.ShellCompDirectiveFilterDirs
351})
352```
353### Descriptions for completions
354
355Cobra provides support for completion descriptions.  Such descriptions are supported for each shell
356(however, for bash, it is only available in the [completion V2 version](#bash-completion-v2)).
357For commands and flags, Cobra will provide the descriptions automatically, based on usage information.
358For example, using zsh:
359```
360$ helm s[tab]
361search  -- search for a keyword in charts
362show    -- show information of a chart
363status  -- displays the status of the named release
364```
365while using fish:
366```
367$ helm s[tab]
368search  (search for a keyword in charts)  show  (show information of a chart)  status  (displays the status of the named release)
369```
370
371Cobra allows you to add descriptions to your own completions.  Simply add the description text after each completion, following a `\t` separator.  This technique applies to completions returned by `ValidArgs`, `ValidArgsFunction` and `RegisterFlagCompletionFunc()`.  For example:
372```go
373ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
374	return []string{"harbor\tAn image registry", "thanos\tLong-term metrics"}, cobra.ShellCompDirectiveNoFileComp
375}}
376```
377or
378```go
379ValidArgs: []string{"bash\tCompletions for bash", "zsh\tCompletions for zsh"}
380```
381## Bash completions
382
383### Dependencies
384
385The 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))
386
387### Aliases
388
389You can also configure `bash` aliases for your program and they will also support completions.
390
391```bash
392alias aliasname=origcommand
393complete -o default -F __start_origcommand aliasname
394
395# and now when you run `aliasname` completion will make
396# suggestions as it did for `origcommand`.
397
398$ aliasname <tab><tab>
399completion     firstcommand   secondcommand
400```
401### Bash legacy dynamic completions
402
403For backward compatibility, Cobra still supports its bash legacy dynamic completion solution.
404Please refer to [Bash Completions](bash_completions.md) for details.
405
406### Bash completion V2
407
408Cobra provides two versions for bash completion.  The original bash completion (which started it all!) can be used by calling
409`GenBashCompletion()` or `GenBashCompletionFile()`.
410
411A new V2 bash completion version is also available.  This version can be used by calling `GenBashCompletionV2()` or
412`GenBashCompletionFileV2()`.  The V2 version does **not** support the legacy dynamic completion
413(see [Bash Completions](bash_completions.md)) but instead works only with the Go dynamic completion
414solution described in this document.
415Unless your program already uses the legacy dynamic completion solution, it is recommended that you use the bash
416completion V2 solution which provides the following extra features:
417- Supports completion descriptions (like the other shells)
418- Small completion script of less than 300 lines (v1 generates scripts of thousands of lines; `kubectl` for example has a bash v1 completion script of over 13K lines)
419- Streamlined user experience thanks to a completion behavior aligned with the other shells
420
421`Bash` completion V2 supports descriptions for completions. When calling `GenBashCompletionV2()` or `GenBashCompletionFileV2()`
422you must provide these functions with a parameter indicating if the completions should be annotated with a description; Cobra
423will provide the description automatically based on usage information.  You can choose to make this option configurable by
424your users.
425
426```
427# With descriptions
428$ helm s[tab][tab]
429search  (search for a keyword in charts)           status  (display the status of the named release)
430show    (show information of a chart)
431
432# Without descriptions
433$ helm s[tab][tab]
434search  show  status
435```
436**Note**: Cobra's default `completion` command uses bash completion V2.  If for some reason you need to use bash completion V1, you will need to implement your own `completion` command.
437## Zsh completions
438
439Cobra supports native zsh completion generated from the root `cobra.Command`.
440The generated completion script should be put somewhere in your `$fpath` and be named
441`_<yourProgram>`.  You will need to start a new shell for the completions to become available.
442
443Zsh supports descriptions for completions. Cobra will provide the description automatically,
444based on usage information. Cobra provides a way to completely disable such descriptions by
445using `GenZshCompletionNoDesc()` or `GenZshCompletionFileNoDesc()`. You can choose to make
446this a configurable option to your users.
447```
448# With descriptions
449$ helm s[tab]
450search  -- search for a keyword in charts
451show    -- show information of a chart
452status  -- displays the status of the named release
453
454# Without descriptions
455$ helm s[tab]
456search  show  status
457```
458*Note*: Because of backward-compatibility requirements, we were forced to have a different API to disable completion descriptions between `zsh` and `fish`.
459
460### Limitations
461
462* Custom completions implemented in Bash scripting (legacy) are not supported and will be ignored for `zsh` (including the use of the `BashCompCustom` flag annotation).
463  * You should instead use `ValidArgsFunction` and `RegisterFlagCompletionFunc()` which are portable to the different shells (`bash`, `zsh`, `fish`, `powershell`).
464* The function `MarkFlagCustom()` is not supported and will be ignored for `zsh`.
465  * You should instead use `RegisterFlagCompletionFunc()`.
466
467### Zsh completions standardization
468
469Cobra 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.
470Please refer to [Zsh Completions](zsh_completions.md) for details.
471
472## fish completions
473
474Cobra 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.
475```
476# With descriptions
477$ helm s[tab]
478search  (search for a keyword in charts)  show  (show information of a chart)  status  (displays the status of the named release)
479
480# Without descriptions
481$ helm s[tab]
482search  show  status
483```
484*Note*: Because of backward-compatibility requirements, we were forced to have a different API to disable completion descriptions between `zsh` and `fish`.
485
486### Limitations
487
488* Custom completions implemented in bash scripting (legacy) are not supported and will be ignored for `fish` (including the use of the `BashCompCustom` flag annotation).
489  * You should instead use `ValidArgsFunction` and `RegisterFlagCompletionFunc()` which are portable to the different shells (`bash`, `zsh`, `fish`, `powershell`).
490* The function `MarkFlagCustom()` is not supported and will be ignored for `fish`.
491  * You should instead use `RegisterFlagCompletionFunc()`.
492* The following flag completion annotations are not supported and will be ignored for `fish`:
493  * `BashCompFilenameExt` (filtering by file extension)
494  * `BashCompSubdirsInDir` (filtering by directory)
495* The functions corresponding to the above annotations are consequently not supported and will be ignored for `fish`:
496  * `MarkFlagFilename()` and `MarkPersistentFlagFilename()` (filtering by file extension)
497  * `MarkFlagDirname()` and `MarkPersistentFlagDirname()` (filtering by directory)
498* Similarly, the following completion directives are not supported and will be ignored for `fish`:
499  * `ShellCompDirectiveFilterFileExt` (filtering by file extension)
500  * `ShellCompDirectiveFilterDirs` (filtering by directory)
501
502## PowerShell completions
503
504Cobra 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.
505
506The script is designed to support all three PowerShell completion modes:
507
508* TabCompleteNext (default windows style - on each key press the next option is displayed)
509* Complete (works like bash)
510* MenuComplete (works like zsh)
511
512You set the mode with `Set-PSReadLineKeyHandler -Key Tab -Function <mode>`. Descriptions are only displayed when using the `Complete` or `MenuComplete` mode.
513
514Users 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.
515
516```
517# With descriptions and Mode 'Complete'
518$ helm s[tab]
519search  (search for a keyword in charts)  show  (show information of a chart)  status  (displays the status of the named release)
520
521# With descriptions and Mode 'MenuComplete' The description of the current selected value will be displayed below the suggestions.
522$ helm s[tab]
523search    show     status
524
525search for a keyword in charts
526
527# Without descriptions
528$ helm s[tab]
529search  show  status
530```
531
532### Limitations
533
534* Custom completions implemented in bash scripting (legacy) are not supported and will be ignored for `powershell` (including the use of the `BashCompCustom` flag annotation).
535  * You should instead use `ValidArgsFunction` and `RegisterFlagCompletionFunc()` which are portable to the different shells (`bash`, `zsh`, `fish`, `powershell`).
536* The function `MarkFlagCustom()` is not supported and will be ignored for `powershell`.
537  * You should instead use `RegisterFlagCompletionFunc()`.
538* The following flag completion annotations are not supported and will be ignored for `powershell`:
539  * `BashCompFilenameExt` (filtering by file extension)
540  * `BashCompSubdirsInDir` (filtering by directory)
541* The functions corresponding to the above annotations are consequently not supported and will be ignored for `powershell`:
542  * `MarkFlagFilename()` and `MarkPersistentFlagFilename()` (filtering by file extension)
543  * `MarkFlagDirname()` and `MarkPersistentFlagDirname()` (filtering by directory)
544* Similarly, the following completion directives are not supported and will be ignored for `powershell`:
545  * `ShellCompDirectiveFilterFileExt` (filtering by file extension)
546  * `ShellCompDirectiveFilterDirs` (filtering by directory)
547