Skip to content

Commit 2c5a0d3

Browse files
authored
Extend Go completions and revamp zsh comp (#1070) (#1070)
Replace the current Zsh completion with a Zsh completion solution based on Go completions. This allows to support custom completions (based on Go completions), but also to standardize the behavior of completion across all shells. Also, add support to Go completions for the bash completion annotations: BashCompFilenameExt (including Command.MarkFlagFilename() family) - still supported by zsh BashCompSubdirsInDir - now supported by zsh BashCompOneRequiredFlag (including Command.MarkFlagRequired() family) - now supported by zsh and fish Finally, remove the suggestin of the = form of flag completion. The = form is supported, but it will not be suggested to avoid having duplicated suggestions.
1 parent 0431872 commit 2c5a0d3

13 files changed

+2254
-1244
lines changed

README.md

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ name a few. [This list](./projects_using_cobra.md) contains a more extensive lis
2828
* [PreRun and PostRun Hooks](#prerun-and-postrun-hooks)
2929
* [Suggestions when "unknown command" happens](#suggestions-when-unknown-command-happens)
3030
* [Generating documentation for your command](#generating-documentation-for-your-command)
31-
* [Generating bash completions](#generating-bash-completions)
32-
* [Generating zsh completions](#generating-zsh-completions)
31+
* [Generating shell completions](#generating-shell-completions)
3332
- [Contributing](#contributing)
3433
- [License](#license)
3534

@@ -50,7 +49,7 @@ Cobra provides:
5049
* Intelligent suggestions (`app srver`... did you mean `app server`?)
5150
* Automatic help generation for commands and flags
5251
* Automatic help flag recognition of `-h`, `--help`, etc.
53-
* Automatically generated bash autocomplete for your application
52+
* Automatically generated shell autocomplete for your application (bash, zsh, fish, powershell)
5453
* Automatically generated man pages for your application
5554
* Command aliases so you can change things without breaking them
5655
* The flexibility to define your own help, usage, etc.
@@ -720,14 +719,9 @@ Run 'kubectl help' for usage.
720719

721720
Cobra can generate documentation based on subcommands, flags, etc. Read more about it in the [docs generation documentation](doc/README.md).
722721

723-
## Generating bash completions
722+
## Generating shell completions
724723

725-
Cobra can generate a bash-completion file. If you add more information to your command, these completions can be amazingly powerful and flexible. Read more about it in [Bash Completions](bash_completions.md).
726-
727-
## Generating zsh completions
728-
729-
Cobra can generate zsh-completion file. Read more about it in
730-
[Zsh Completions](zsh_completions.md).
724+
Cobra can generate a shell-completion file for the following shells: Bash, Zsh, Fish, Powershell. If you add more information to your commands, these completions can be amazingly powerful and flexible. Read more about it in [Shell Completions](shell_completions.md).
731725

732726
# Contributing
733727

bash_completions.go

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ __%[1]s_handle_go_custom_completion()
6262
{
6363
__%[1]s_debug "${FUNCNAME[0]}: cur is ${cur}, words[*] is ${words[*]}, #words[@] is ${#words[@]}"
6464
65+
local shellCompDirectiveError=%[3]d
66+
local shellCompDirectiveNoSpace=%[4]d
67+
local shellCompDirectiveNoFileComp=%[5]d
68+
local shellCompDirectiveFilterFileExt=%[6]d
69+
local shellCompDirectiveFilterDirs=%[7]d
70+
6571
local out requestComp lastParam lastChar comp directive args
6672
6773
# Prepare the command to request completions for the program.
@@ -95,24 +101,50 @@ __%[1]s_handle_go_custom_completion()
95101
__%[1]s_debug "${FUNCNAME[0]}: the completion directive is: ${directive}"
96102
__%[1]s_debug "${FUNCNAME[0]}: the completions are: ${out[*]}"
97103
98-
if [ $((directive & %[3]d)) -ne 0 ]; then
104+
if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then
99105
# Error code. No completion.
100106
__%[1]s_debug "${FUNCNAME[0]}: received error from custom completion go code"
101107
return
102108
else
103-
if [ $((directive & %[4]d)) -ne 0 ]; then
109+
if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then
104110
if [[ $(type -t compopt) = "builtin" ]]; then
105111
__%[1]s_debug "${FUNCNAME[0]}: activating no space"
106112
compopt -o nospace
107113
fi
108114
fi
109-
if [ $((directive & %[5]d)) -ne 0 ]; then
115+
if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then
110116
if [[ $(type -t compopt) = "builtin" ]]; then
111117
__%[1]s_debug "${FUNCNAME[0]}: activating no file completion"
112118
compopt +o default
113119
fi
114120
fi
121+
fi
115122
123+
if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
124+
# File extension filtering
125+
local fullFilter filter filteringCmd
126+
# Do not use quotes around the $out variable or else newline
127+
# characters will be kept.
128+
for filter in ${out[*]}; do
129+
fullFilter+="$filter|"
130+
done
131+
132+
filteringCmd="_filedir $fullFilter"
133+
__%[1]s_debug "File filtering command: $filteringCmd"
134+
$filteringCmd
135+
elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then
136+
# File completion for directories only
137+
local subDir
138+
# Use printf to strip any trailing newline
139+
subdir=$(printf "%%s" "${out[0]}")
140+
if [ -n "$subdir" ]; then
141+
__%[1]s_debug "Listing directories in $subdir"
142+
__%[1]s_handle_subdirs_in_dir_flag "$subdir"
143+
else
144+
__%[1]s_debug "Listing directories in ."
145+
_filedir -d
146+
fi
147+
else
116148
while IFS='' read -r comp; do
117149
COMPREPLY+=("$comp")
118150
done < <(compgen -W "${out[*]}" -- "$cur")
@@ -343,7 +375,9 @@ __%[1]s_handle_word()
343375
__%[1]s_handle_word
344376
}
345377
346-
`, name, ShellCompNoDescRequestCmd, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp))
378+
`, name, ShellCompNoDescRequestCmd,
379+
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
380+
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs))
347381
}
348382

349383
func writePostscript(buf *bytes.Buffer, name string) {

0 commit comments

Comments
 (0)