Closed indrat closed 1 year ago
hi! I'm having trouble reproducing this:
tsutsumi:/home/tsutsumi/.ytlaces/cookbook/t (0)
$ s t bar --bar1
--bar1 --bar2 --not-bar
(it just cycles through the three options for me). This is with tome 0.9.0, zsh 5.9, arch linux. I feel like the debian / arch difference is likely not the culprit.
The call to compgen is here: https://github.com/toumorokoshi/tome/blob/master/src/commands/init.rs#L48.
And the relevant part is:
all_options=`{tome_executable} command-complete {script_root} -s {shell} -- $tome_args`
valid_options=$(compgen -W "$all_options" "$token_to_complete")
which makes me wonder what that token_to_complete
is for you? it should be quoted, but perhaps it's being interpreted as an actual flag.
Or your compgen varies from mind for some reason (which it shouldn't be, zsh provides it).
can you try:
tome command-complete {your_script_root} -s zsh -- bar --
to see what it outputs?
Sure, the output is below:
$ cat $PWD/example/dir_example/bar
#!/usr/bin/env bash
# COMPLETE
if [[ "$1" == "--complete" ]]; then
echo "--bar1 --bar2 --not-bar"
exit
fi
echo "COMMAND: bar $*"
$ tome command-complete $PWD/example/dir_example -s zsh -- bar --
--bar1 --bar2 --not-bar
Calling compgen directly based on the linked rust code:
$ compgen -W "--bar1 --bar2 --not-bar" "--"
--bar1
--bar2
--not-bar
$ compgen -W "--bar1 --bar2 --not-bar" "--b"
compgen:14: bad option: --
--bar1
--bar2
--not-bar
unset
rehash
popd
....
In an attempt to remove as much of my environment as possible I also built a container with:
FROM debian:bookworm
RUN /bin/true \
&& apt update \
&& apt install -y \
zsh \
curl \
&& curl -L -o /usr/local/bin/tome https://github.com/toumorokoshi/tome/releases/download/v0.9.0/tome-linux_amd64 \
&& chmod ugo+x /usr/local/bin/tome \
&& echo 'eval "$(tome init tool /usr/local/scripts zsh)"' > /root/.zshrc
$ podman build -t tome-test .
$ podman run --rm -it -v ${PWD}/example/dir_example:/usr/local/scripts localhost/tome-test:latest /bin/zsh
599e767dd146# tool bar --b<TAB>compgen:14: bad option: --
--bar1 --bar2 --noarbar
815f45867787# compgen -W "--bar1 --bar2 --not-bar" "--b"
compgen:14: bad option: --
--bar1
--bar2
--not-bar
awesome, thank you for the container repro! I'll take a look.
so I was able to repro. compgen function in question:
compgen () {
local opts prefix suffix job OPTARG OPTIND ret=1
local -a name res results jids
local -A shortopts
emulate -L sh
setopt kshglob noshglob braceexpand nokshautoload
shortopts=(a alias b builtin c command d directory e export f file g group j job k keyword u user v variable)
while getopts "o:A:G:C:F:P:S:W:X:abcdefgjkuv" name
do
case $name in
([abcdefgjkuv]) OPTARG="${shortopts[$name]}" ;&
(A) case $OPTARG in
(alias) results+=("${(k)aliases[@]}") ;;
(arrayvar) results+=("${(k@)parameters[(R)array*]}") ;;
(binding) results+=("${(k)widgets[@]}") ;;
(builtin) results+=("${(k)builtins[@]}" "${(k)dis_builtins[@]}") ;;
(command) results+=("${(k)commands[@]}" "${(k)aliases[@]}" "${(k)builtins[@]}" "${(k)functions[@]}" "${(k)reswords[@]}") ;;
(directory) setopt bareglobqual
results+=(${IPREFIX}${PREFIX}*${SUFFIX}${ISUFFIX}(N-/))
setopt nobareglobqual ;;
(disabled) results+=("${(k)dis_builtins[@]}") ;;
(enabled) results+=("${(k)builtins[@]}") ;;
(export) results+=("${(k)parameters[(R)*export*]}") ;;
(file) setopt bareglobqual
results+=(${IPREFIX}${PREFIX}*${SUFFIX}${ISUFFIX}(N))
setopt nobareglobqual ;;
(function) results+=("${(k)functions[@]}") ;;
(group) emulate zsh
_groups -U -O res
emulate sh
setopt kshglob noshglob braceexpand
results+=("${res[@]}") ;;
(hostname) emulate zsh
_hosts -U -O res
emulate sh
setopt kshglob noshglob braceexpand
results+=("${res[@]}") ;;
(job) results+=("${savejobtexts[@]%% *}") ;;
(keyword) results+=("${(k)reswords[@]}") ;;
(running) jids=("${(@k)savejobstates[(R)running*]}")
for job in "${jids[@]}"
do
results+=(${savejobtexts[$job]%% *})
done ;;
(stopped) jids=("${(@k)savejobstates[(R)suspended*]}")
for job in "${jids[@]}"
do
results+=(${savejobtexts[$job]%% *})
done ;;
(setopt | shopt) results+=("${(k)options[@]}") ;;
(signal) results+=("SIG${^signals[@]}") ;;
(user) results+=("${(k)userdirs[@]}") ;;
(variable) results+=("${(k)parameters[@]}") ;;
(helptopic) ;;
esac ;;
(F) COMPREPLY=()
local -a args
args=("${words[0]}" "${@[-1]}" "${words[CURRENT-2]}")
() {
typeset -h words
$OPTARG "${args[@]}"
}
results+=("${COMPREPLY[@]}") ;;
(G) setopt nullglob
results+=(${~OPTARG})
unsetopt nullglob ;;
(W) results+=(${(Q)~=OPTARG}) ;;
(C) results+=($(eval $OPTARG)) ;;
(P) prefix="$OPTARG" ;;
(S) suffix="$OPTARG" ;;
(X) if [[ ${OPTARG[0]} = '!' ]]
then
results=("${(M)results[@]:#${OPTARG#?}}")
else
results=("${results[@]:#$OPTARG}")
fi ;;
esac
done
print -l -r -- "$prefix${^results[@]}$suffix"
}
and my compgen which worked:
compgen () {
local opts prefix suffix job OPTARG OPTIND ret=1
local -a name res results jids
local -A shortopts
emulate -L sh
setopt kshglob noshglob braceexpand nokshautoload
shortopts=(a alias b builtin c command d directory e export f file g group j job k keyword u user v variable)
while getopts "o:A:G:C:F:P:S:W:X:abcdefgjkuv" name
do
case $name in
([abcdefgjkuv]) OPTARG="${shortopts[$name]}" ;&
(A) case $OPTARG in
(alias) results+=("${(k)aliases[@]}") ;;
(arrayvar) results+=("${(k@)parameters[(R)array*]}") ;;
(binding) results+=("${(k)widgets[@]}") ;;
(builtin) results+=("${(k)builtins[@]}" "${(k)dis_builtins[@]}") ;;
(command) results+=("${(k)commands[@]}" "${(k)aliases[@]}" "${(k)builtins[@]}" "${(k)functions[@]}" "${(k)reswords[@]}") ;;
(directory) setopt bareglobqual
results+=(${IPREFIX}${PREFIX}*${SUFFIX}${ISUFFIX}(N-/))
setopt nobareglobqual ;;
(disabled) results+=("${(k)dis_builtins[@]}") ;;
(enabled) results+=("${(k)builtins[@]}") ;;
(export) results+=("${(k)parameters[(R)*export*]}") ;;
(file) setopt bareglobqual
results+=(${IPREFIX}${PREFIX}*${SUFFIX}${ISUFFIX}(N))
setopt nobareglobqual ;;
(function) results+=("${(k)functions[@]}") ;;
(group) emulate zsh
_groups -U -O res
emulate sh
setopt kshglob noshglob braceexpand
results+=("${res[@]}") ;;
(hostname) emulate zsh
_hosts -U -O res
emulate sh
setopt kshglob noshglob braceexpand
results+=("${res[@]}") ;;
(job) results+=("${savejobtexts[@]%% *}") ;;
(keyword) results+=("${(k)reswords[@]}") ;;
(running) jids=("${(@k)savejobstates[(R)running*]}")
for job in "${jids[@]}"
do
results+=(${savejobtexts[$job]%% *})
done ;;
(stopped) jids=("${(@k)savejobstates[(R)suspended*]}")
for job in "${jids[@]}"
do
results+=(${savejobtexts[$job]%% *})
done ;;
(setopt | shopt) results+=("${(k)options[@]}") ;;
(signal) results+=("SIG${^signals[@]}") ;;
(user) results+=("${(k)userdirs[@]}") ;;
(variable) results+=("${(k)parameters[@]}") ;;
(helptopic) ;;
esac ;;
(F) COMPREPLY=()
local -a args
args=("${words[0]}" "${@[-1]}" "${words[CURRENT-2]}")
() {
typeset -h words
$OPTARG "${args[@]}"
}
results+=("${COMPREPLY[@]}") ;;
(G) setopt nullglob
results+=(${~OPTARG})
unsetopt nullglob ;;
(W) results+=(${(Q)~=OPTARG}) ;;
(C) results+=($(eval $OPTARG)) ;;
(P) prefix="$OPTARG" ;;
(S) suffix="$OPTARG" ;;
(X) if [[ ${OPTARG[0]} = '!' ]]
then
results=("${(M)results[@]:#${OPTARG#?}}")
else
results=("${results[@]:#$OPTARG}")
fi ;;
esac
done
print -l -r -- "$prefix${^results[@]}$suffix"
}
I was able to repro and produce a fix (#47), shipped in 0.10.0 (just released). Please try it! and feel free to re-open if it doesn't fix your issue.
Works great! Thanks for the fix 👍
System/Version debian:12, zsh: 5.9, tome v0.9.0 macOS 12.6, zsh: 5.8.1, tome v0.9.0
Example command (modified
example/dir_example/bar
:Behaviour: after typing results in additional compgen warnings being printed however, the argument is completed.
--<TAB>
the tab complete options are displayed correctly however after typing the next character and typing<TAB>
a compgen warning is printed. Continuing to type