-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New zsh completion script seems broken #881
Comments
Maybe similar: kubernetes-sigs/kind#522 (comment) Can look at it tomorrow. |
Hey @corneliusweig Sadly I can't reproduce it. I copied the generated script you posted to somewhere in my Can you please copy the file to somewhere in your Regarding sourcing the completion script, I'm not sure it works. I don't think I ever tested for it, nor was it a target of mine when I wrote it. In my opinion completion scripts should not be manually sourced. I have hundreds of them and it doesn't make sense to load them separately 🙂. |
@babysnakes That does not seem to work either. I am using zsh 5.6.2 with oh-my-zsh. I think that being able to source the generated script is a major use-case for cobra completion. For example, that is how |
Hey @corneliusweig, Let's tackle the sourcing issue later (I'm not even sure what it takes, I have to look). First let's get it working. I installed docker with oh-my-zsh - default installation, didn't do anything beside the install command - and at first it didn't work. however, after I ran |
Hey @babysnakes, thanks for your quick response. Indeed it works also on my system, when I do
So that is resolved then. Now what about the direct sourcing, though. I was looking at the old code from the skaffold completion (which uses a zsh wrapper around the bash completion, see below). I wonder why that works without the indirection via a file. In other words, just doing a #compdef skaffold
__skaffold_bash_source() {
alias shopt=':'
alias _expand=_bash_expand
alias _complete=_bash_comp
emulate -L sh
setopt kshglob noshglob braceexpand
source "$@"
}
__skaffold_type() {
# -t is not supported by zsh
if [ "$1" == "-t" ]; then
shift
# fake Bash 4 to disable "complete -o nospace". Instead
# "compopt +-o nospace" is used in the code to toggle trailing
# spaces. We don't support that, but leave trailing spaces on
# all the time
if [ "$1" = "__skaffold_compopt" ]; then
echo builtin
return 0
fi
fi
type "$@"
}
__skaffold_compgen() {
local completions w
completions=( $(compgen "$@") ) || return $?
# filter by given word as prefix
while [[ "$1" = -* && "$1" != -- ]]; do
shift
shift
done
if [[ "$1" == -- ]]; then
shift
fi
for w in "${completions[@]}"; do
if [[ "${w}" = "$1"* ]]; then
echo "${w}"
fi
done
}
__skaffold_compopt() {
true # don't do anything. Not supported by bashcompinit in zsh
}
__skaffold_ltrim_colon_completions()
{
if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
# Remove colon-word prefix from COMPREPLY items
local colon_word=${1%${1##*:}}
local i=${#COMPREPLY[*]}
while [[ $((--i)) -ge 0 ]]; do
COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
done
fi
}
__skaffold_get_comp_words_by_ref() {
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[${COMP_CWORD}-1]}"
words=("${COMP_WORDS[@]}")
cword=("${COMP_CWORD[@]}")
}
__skaffold_filedir() {
local RET OLD_IFS w qw
__skaffold_debug "_filedir $@ cur=$cur"
if [[ "$1" = \~* ]]; then
# somehow does not work. Maybe, zsh does not call this at all
eval echo "$1"
return 0
fi
OLD_IFS="$IFS"
IFS=$'\n'
if [ "$1" = "-d" ]; then
shift
RET=( $(compgen -d) )
else
RET=( $(compgen -f) )
fi
IFS="$OLD_IFS"
IFS="," __skaffold_debug "RET=${RET[@]} len=${#RET[@]}"
for w in ${RET[@]}; do
if [[ ! "${w}" = "${cur}"* ]]; then
continue
fi
if eval "[[ \"\${w}\" = *.$1 || -d \"\${w}\" ]]"; then
qw="$(__skaffold_quote "${w}")"
if [ -d "${w}" ]; then
COMPREPLY+=("${qw}/")
else
COMPREPLY+=("${qw}")
fi
fi
done
}
__skaffold_quote() {
if [[ $1 == \'* || $1 == \"* ]]; then
# Leave out first character
printf %q "${1:1}"
else
printf %q "$1"
fi
}
autoload -U +X bashcompinit && bashcompinit
# use word boundary patterns for BSD or GNU sed
LWORD='[[:<:]]'
RWORD='[[:>:]]'
if sed --help 2>&1 | grep -q GNU; then
LWORD='\<'
RWORD='\>'
fi
__skaffold_convert_bash_to_zsh() {
sed \
-e 's/declare -F/whence -w/' \
-e 's/_get_comp_words_by_ref "\$@"/_get_comp_words_by_ref "\$*"/' \
-e 's/local \([a-zA-Z0-9_]*\)=/local \1; \1=/' \
-e 's/flags+=("\(--.*\)=")/flags+=("\1"); two_word_flags+=("\1")/' \
-e 's/must_have_one_flag+=("\(--.*\)=")/must_have_one_flag+=("\1")/' \
-e "s/${LWORD}_filedir${RWORD}/__skaffold_filedir/g" \
-e "s/${LWORD}_get_comp_words_by_ref${RWORD}/__skaffold_get_comp_words_by_ref/g" \
-e "s/${LWORD}__ltrim_colon_completions${RWORD}/__skaffold_ltrim_colon_completions/g" \
-e "s/${LWORD}compgen${RWORD}/__skaffold_compgen/g" \
-e "s/${LWORD}compopt${RWORD}/__skaffold_compopt/g" \
-e "s/${LWORD}declare${RWORD}/builtin declare/g" \
-e "s/\\\$(type${RWORD}/\$(__skaffold_type/g" \
<<'BASH_COMPLETION_EOF'
#######################################
# output of `skaffold completion bash` removed
#######################################
BASH_COMPLETION_EOF
}
__skaffold_bash_source <(__skaffold_convert_bash_to_zsh)
_complete skaffold 2>/dev/null
|
Hey @corneliusweig I'm not sure what it takes. playing around with it a little I got the infamous error of |
Hey @corneliusweig I'm sorry but looking at it a little further it doesn't seem it can work. Zsh has more then one completion systems. I used the one that is used by the great zsh-users/zsh-completion project. It offers all the niceties of having descriptions on completion, etc. However, it seems that this system can only be used as files inside I'm not sure I can offer any solution for that 🙁 |
@corneliusweig i think the magic happens here: Regarding adding the completion without fpath this seems to be actually possible with manual invocation of autoload -Uz compinit && compinit -C
source <(skaffold completion zsh)
compdef _skaffold skaffold This is certainly easier to use but skips all the caching mechanisms of zsh regarding the completion system. AFAIK those from fpath see http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Use-of-compinit (seems i had some assumptions wrong regarding the |
@rsteube Thanks for investigating this! I think it is safe to assume that diff --git a/zsh_completions.go b/zsh_completions.go
index 1275548..538c3f7 100644
--- a/zsh_completions.go
+++ b/zsh_completions.go
@@ -80,6 +80,7 @@ function {{genZshFuncName .}} {
#compdef _{{.Name}} {{.Name}}
{{template "selectCmdTemplate" .}}
+compdef _{{.Name}} {{.Name}}
{{end}}
`
) In my manual test that worked like a charm. The question is: does the extra |
Yes, i was thinking the same and had tried it out successfully as well. Here's some documentation regarding the header line: http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Autoloaded-files |
Hey @rsteube @corneliusweig I'm running into this issue, and I applied your suggested fix: #881 (comment) So, now the tab does something, but I run into this error upon tab with global flags:
|
That looks more like a problem in the completion script itself. Did a short search and this came up: clap-rs/clap#771 (comment) Are there some special characters in that line (like the square brackets)? I had a problem with the brackets myself in one completion and needed to add quotation for that. see: #885 |
Cool, thanks @rsteube |
@rsteube Sounds fine to add that here as well. Do you want to open a PR? Otherwise I'll do that :) |
can do - just a sec |
@rsteube very cool, learned something new today 🙂. |
This issue is being marked as stale due to a long period of inactivity |
I'll close this, because it looks like the cobra authors are happy with the standard zsh way of putting the script into fpath. |
@corneliusweig i don't remember it exactly but i did notice a small side effect with the explicit so instead of: btw. i did some more work on this here: https://github.com/rsteube/carapace |
I just tried the zsh completion as merged recently via #646. Unfortunately, I couldn't get it to work for example with
skaffold
(https://github.com/corneliusweig/skaffold/tree/upgrade-cobra).The generated completion script looks ok (see below), but when I type
skaffold <Tab><Tab>
, I only get files from my current directory as suggestion instead of subcommands and options. I have sourced the generated completion script in a running zsh viasource skaffold-completion.zsh
./cc @rsteube @babysnakes (because you were active on the referenced PR)
The text was updated successfully, but these errors were encountered: