Dynamic Completion Engine
Cobra’s completion engine turns a partially typed command line into completion candidates for commands, positional arguments, and flag values. The hidden __complete request command returns candidates together with a ShellCompDirective.
It exists so generated shell scripts can ask the running program for context-sensitive results. Applications can provide dynamic positional candidates with ValidArgsFunction and register dynamic flag-value providers with RegisterFlagCompletionFunc.
Sources: completions.go:31, completions.go:231-306, command.go:87-90, completions.go:170-183
Core concepts
Completion request
A completion request is the hidden __complete command, which also has the alias __completeNoDesc.
Sources: completions.go:31, completions.go:34, completions.go:231-306
Positional completion
Positional completion supplies non-flag arguments dynamically through ValidArgsFunction.
Use ValidArgsFunction when positional candidates are computed at completion time. NoFileCompletions is the supplied helper for returning no candidates with ShellCompDirectiveNoFileComp.
Sources: command.go:87-90, completions.go:151-153
Flag-value completion
Flag-value completion supplies candidates for a flag through a registered CompletionFunc.
RegisterFlagCompletionFunc looks up the named flag, rejects missing or duplicate registrations, and stores the function in flagCompletionFunctions while holding flagCompletionMutex.
Sources: completions.go:170-183, completions.go:186-197, completions.go:38, completions.go:41
Completion directive
A completion directive is a bit-field value returned alongside completion candidates.
| Directive | What the supplied code establishes |
|---|---|
ShellCompDirectiveDefault | Its value is zero. |
ShellCompDirectiveError | It is an error bit in the directive set. |
ShellCompDirectiveNoSpace | It is a named directive bit. |
ShellCompDirectiveNoFileComp | It is a named directive bit, and NoFileCompletions returns it. |
ShellCompDirectiveFilterFileExt | It is a named directive bit used when filename extensions are selected. |
ShellCompDirectiveFilterDirs | It is a named directive bit exposed to generated shell adapters. |
ShellCompDirectiveKeepOrder | It is a named directive bit exposed to generated shell adapters. |
The supplied excerpts establish these declarations and output names, but do not document the shell-side behavior of every bit; the verified file-completion behavior comes from NoFileCompletions and the positional-completion comments.
The directive names are rendered for diagnostics, zero is rendered as ShellCompDirectiveDefault, and values at or above shellCompDirectiveMaxValue are reported as unexpected.
Sources: completions.go:58, completions.go:62, completions.go:66, completions.go:95, completions.go:151-153, completions.go:200-228
How a root gets scheduled for completion
Normal execution initializes the hidden request command and then initializes the default public completion command. The hidden request command is retained only when the current arguments call or complete it, avoiding a permanent subcommand in programs that do not need it.
The main boundaries are:
Evidence
- root-executioncommand.go:1089
- hidden-requestcompletions.go:231
- completion-resolvercompletions.go:316
- flag-registrycompletions.go:38
- flag-registrycompletions.go:170
When the hidden command runs, it calls getCompletions, reports an error through CompErrorln while continuing, writes candidates to standard output, and finally writes :<directive> for the completion script. The handler can remove descriptions, remove active-help entries, trim line breaks, and write diagnostics to standard error.
The request path is:
Evidence
- executecommand.go:1089
- initializercompletions.go:231
- request-commandcompletions.go:31
- request-commandcompletions.go:231
- resolvercompletions.go:316
- flag-checkcompletions.go:657
CompletionWithDesc represents a candidate and description as one tab-separated string. The request handler removes that description when the no-description mode is active.
Sources: command.go:1089-1113, completions.go:231-306, completions.go:142-144
How positional and flag values are resolved
getCompletions removes the final incomplete argument into toComplete, copies the preceding arguments, and finds the real command before parsing completion state. It traverses or finds that command, initializes default help and version flags when flag parsing is enabled, and then checks whether the request concerns a flag value.
For positional completion, configure the command’s ValidArgsFunction. The supplied command model defines it as the dynamic alternative to ValidArgs; the shown resolver excerpt establishes the surrounding resolution path but does not show the later invocation of that function.
For a flag value, call RegisterFlagCompletionFunc with the flag name and a CompletionFunc. The function can later be retrieved with GetFlagCompletionFunc, which looks up the same flag and reads the registry under flagCompletionMutex.
checkIfFlagCompletion recognizes --flag=value and a preceding flag whose value is the next argument. It removes an unfinished flag token from the parse input when necessary, resolves the flag with findFlag, and returns a flagCompError when the flag is unsupported by the command.
Flag annotations provide additional completion metadata. MarkFlagFilename records filename extensions, MarkFlagDirname records directory completion, and MarkFlagCustom records a custom shell completion function. The resolver checks filename annotations and returns ShellCompDirectiveFilterFileExt when extensions are present.
Sources: completions.go:316-585, command.go:87-90, completions.go:170-183, completions.go:186-197, completions.go:657-741, shell_completions.go:67-69, shell_completions.go:96-98, shell_completions.go:77-79
How directives and output reach the shell
After flag parsing, the resolver checks whether the help or version flag was explicitly selected. If so, it returns no candidates with ShellCompDirectiveNoFileComp. The hidden command prints each candidate and then prints the directive as the final :<directive> line.
Generated Bash, zsh, Fish, and PowerShell adapters embed the directive names so their scripts can parse the returned directive values.
CompletionOptions can disable the default command, disable descriptions, hide the default command, and set a default directive. SetDefaultShellCompDirective stores that directive in DefaultShellCompDirective.
Debug output is separated from candidate output. CompDebug can append to the file named by BASH_COMP_DEBUG_FILE and can write to standard error; CompError formats an error and sends it through CompDebug.
Sources: completions.go:316-585, completions.go:587-597, completions.go:231-306, bash_completions.go:399-401, zsh_completions.go:304-307, fish_completions.go:270-273, powershell_completions.go:308-311, completions.go:107-121, completions.go:123-125, completions.go:955-974, completions.go:985-988
How it connects
The command model supplies ValidArgsFunction, Args, and the command tree that completion resolves. See Cobra Overview and Command Tree & Registration.
Flag parsing supplies the flags inspected during completion, including inherited and non-inherited flags. See Flag Parsing & Persistent Flags and Flag Groups: Required, One-Required, Mutually Exclusive.
Generated shell scripts call the hidden request path and consume its candidates and final directive. See Bash Completion Scripts (V1 & V2) and Zsh, Fish & PowerShell Completions.
Sources: command.go:87-94, completions.go:316-585, completions.go:632-655, completions.go:231-306, bash_completions.go:399-401
Key takeaways
__completeis a hidden request command that prints completion candidates and a final directive.- Use
ValidArgsFunctionfor dynamic positional candidates andRegisterFlagCompletionFuncfor flag-value providers. checkIfFlagCompletiondistinguishes flag names from flag values, including--flag=valueand space-separated values.NoFileCompletionsreturnsShellCompDirectiveNoFileComp; filename annotations can returnShellCompDirectiveFilterFileExt.- Candidate output goes to standard output, while diagnostics and debug information use separate paths.
Sources: completions.go:31, completions.go:231-306, command.go:87-90, completions.go:170-183, completions.go:657-741, completions.go:151-153, completions.go:316-585, completions.go:955-974