Skip to content

Commit 7338942

Browse files
corneliusweigdgageot
authored andcommitted
Use native zsh completion script generator (#3137)
* Use native zsh completion script generator So far, Skaffold used a wrapper code borrowed from kubectl to use the bash completion script for zsh. Cobra v0.0.5 introduced a native completion script generator for zsh. To support the `source <(...)` use-case, a minor tweak is necessary (also see spf13/cobra#887) Signed-off-by: Cornelius Weig <[email protected]> * Do not explicitly ignore write errors
1 parent f31c3d0 commit 7338942

File tree

1 file changed

+3
-177
lines changed

1 file changed

+3
-177
lines changed

cmd/skaffold/app/cmd/completion.go

Lines changed: 3 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,9 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
/*
18-
NOTICE: The zsh wrapper code below is derived from the completion code
19-
in kubectl (k8s.io/kubernetes/pkg/kubectl/cmd/completion/completion.go),
20-
with the following license:
21-
22-
Copyright 2016 The Kubernetes Authors.
23-
24-
Licensed under the Apache License, Version 2.0 (the "License");
25-
you may not use this file except in compliance with the License.
26-
You may obtain a copy of the License at
27-
28-
http://www.apache.org/licenses/LICENSE-2.0
29-
30-
Unless required by applicable law or agreed to in writing, software
31-
distributed under the License is distributed on an "AS IS" BASIS,
32-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33-
See the License for the specific language governing permissions and
34-
limitations under the License.
35-
*/
36-
3717
package cmd
3818

3919
import (
40-
"bytes"
4120
"fmt"
4221
"io"
4322
"os"
@@ -65,157 +44,7 @@ const (
6544
Additionally, you may want to output the completion to a file and source in your .bashrc
6645
`
6746

68-
zshInitialization = `#compdef skaffold
69-
70-
__skaffold_bash_source() {
71-
alias shopt=':'
72-
alias _expand=_bash_expand
73-
alias _complete=_bash_comp
74-
emulate -L sh
75-
setopt kshglob noshglob braceexpand
76-
77-
source "$@"
78-
}
79-
80-
__skaffold_type() {
81-
# -t is not supported by zsh
82-
if [ "$1" == "-t" ]; then
83-
shift
84-
85-
# fake Bash 4 to disable "complete -o nospace". Instead
86-
# "compopt +-o nospace" is used in the code to toggle trailing
87-
# spaces. We don't support that, but leave trailing spaces on
88-
# all the time
89-
if [ "$1" = "__skaffold_compopt" ]; then
90-
echo builtin
91-
return 0
92-
fi
93-
fi
94-
type "$@"
95-
}
96-
97-
__skaffold_compgen() {
98-
local completions w
99-
completions=( $(compgen "$@") ) || return $?
100-
101-
# filter by given word as prefix
102-
while [[ "$1" = -* && "$1" != -- ]]; do
103-
shift
104-
shift
105-
done
106-
if [[ "$1" == -- ]]; then
107-
shift
108-
fi
109-
for w in "${completions[@]}"; do
110-
if [[ "${w}" = "$1"* ]]; then
111-
echo "${w}"
112-
fi
113-
done
114-
}
115-
116-
__skaffold_compopt() {
117-
true # don't do anything. Not supported by bashcompinit in zsh
118-
}
119-
120-
__skaffold_ltrim_colon_completions()
121-
{
122-
if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
123-
# Remove colon-word prefix from COMPREPLY items
124-
local colon_word=${1%${1##*:}}
125-
local i=${#COMPREPLY[*]}
126-
while [[ $((--i)) -ge 0 ]]; do
127-
COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
128-
done
129-
fi
130-
}
131-
132-
__skaffold_get_comp_words_by_ref() {
133-
cur="${COMP_WORDS[COMP_CWORD]}"
134-
prev="${COMP_WORDS[${COMP_CWORD}-1]}"
135-
words=("${COMP_WORDS[@]}")
136-
cword=("${COMP_CWORD[@]}")
137-
}
138-
139-
__skaffold_filedir() {
140-
local RET OLD_IFS w qw
141-
142-
__skaffold_debug "_filedir $@ cur=$cur"
143-
if [[ "$1" = \~* ]]; then
144-
# somehow does not work. Maybe, zsh does not call this at all
145-
eval echo "$1"
146-
return 0
147-
fi
148-
149-
OLD_IFS="$IFS"
150-
IFS=$'\n'
151-
if [ "$1" = "-d" ]; then
152-
shift
153-
RET=( $(compgen -d) )
154-
else
155-
RET=( $(compgen -f) )
156-
fi
157-
IFS="$OLD_IFS"
158-
159-
IFS="," __skaffold_debug "RET=${RET[@]} len=${#RET[@]}"
160-
161-
for w in ${RET[@]}; do
162-
if [[ ! "${w}" = "${cur}"* ]]; then
163-
continue
164-
fi
165-
if eval "[[ \"\${w}\" = *.$1 || -d \"\${w}\" ]]"; then
166-
qw="$(__skaffold_quote "${w}")"
167-
if [ -d "${w}" ]; then
168-
COMPREPLY+=("${qw}/")
169-
else
170-
COMPREPLY+=("${qw}")
171-
fi
172-
fi
173-
done
174-
}
175-
176-
__skaffold_quote() {
177-
if [[ $1 == \'* || $1 == \"* ]]; then
178-
# Leave out first character
179-
printf %q "${1:1}"
180-
else
181-
printf %q "$1"
182-
fi
183-
}
184-
185-
autoload -U +X bashcompinit && bashcompinit
186-
187-
# use word boundary patterns for BSD or GNU sed
188-
LWORD='[[:<:]]'
189-
RWORD='[[:>:]]'
190-
if sed --help 2>&1 | grep -q GNU; then
191-
LWORD='\<'
192-
RWORD='\>'
193-
fi
194-
195-
__skaffold_convert_bash_to_zsh() {
196-
sed \
197-
-e 's/declare -F/whence -w/' \
198-
-e 's/_get_comp_words_by_ref "\$@"/_get_comp_words_by_ref "\$*"/' \
199-
-e 's/local \([a-zA-Z0-9_]*\)=/local \1; \1=/' \
200-
-e 's/flags+=("\(--.*\)=")/flags+=("\1"); two_word_flags+=("\1")/' \
201-
-e 's/must_have_one_flag+=("\(--.*\)=")/must_have_one_flag+=("\1")/' \
202-
-e "s/${LWORD}_filedir${RWORD}/__skaffold_filedir/g" \
203-
-e "s/${LWORD}_get_comp_words_by_ref${RWORD}/__skaffold_get_comp_words_by_ref/g" \
204-
-e "s/${LWORD}__ltrim_colon_completions${RWORD}/__skaffold_ltrim_colon_completions/g" \
205-
-e "s/${LWORD}compgen${RWORD}/__skaffold_compgen/g" \
206-
-e "s/${LWORD}compopt${RWORD}/__skaffold_compopt/g" \
207-
-e "s/${LWORD}declare${RWORD}/builtin declare/g" \
208-
-e "s/\\\$(type${RWORD}/\$(__skaffold_type/g" \
209-
<<'BASH_COMPLETION_EOF'
210-
`
211-
212-
zshTail = `
213-
BASH_COMPLETION_EOF
214-
}
215-
216-
__skaffold_bash_source <(__skaffold_convert_bash_to_zsh)
217-
_complete skaffold 2>/dev/null
218-
`
47+
zshCompdef = "\ncompdef _skaffold skaffold\n"
21948
)
22049

22150
func completion(cmd *cobra.Command, args []string) {
@@ -245,11 +74,8 @@ func NewCmdCompletion() *cobra.Command {
24574
}
24675

24776
func runCompletionZsh(cmd *cobra.Command, out io.Writer) {
248-
io.WriteString(out, zshInitialization)
249-
buf := new(bytes.Buffer)
250-
rootCmd(cmd).GenBashCompletion(buf)
251-
out.Write(buf.Bytes())
252-
io.WriteString(out, zshTail)
77+
rootCmd(cmd).GenZshCompletion(out)
78+
io.WriteString(out, zshCompdef)
25379
}
25480

25581
func rootCmd(cmd *cobra.Command) *cobra.Command {

0 commit comments

Comments
 (0)