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