improve command and completions
This commit is contained in:
@@ -4,41 +4,85 @@ _comp_cmd_goto() {
|
||||
local cur prev words cword comp_args
|
||||
_comp_initialize -- "$@" || return
|
||||
|
||||
# echo "[$cur] [$prev] [${words[@]}] [$cword] [$comp_args]"
|
||||
# the list of valid options with their argument requirement
|
||||
# it is updated as the command is parsed
|
||||
local -A valid_opts=([-a]=true [-r]=true [-g]=true [-e]=false [-l]=false [-t]=false)
|
||||
# how many positional arguments are expected
|
||||
local -i expected_positional_args=1
|
||||
# optionals and positionals read up to, not including ${cword} (current word index)
|
||||
local -i opt_args=0 positional_args=0
|
||||
# holds an option that requires its argument to be read next
|
||||
local expected_optarg
|
||||
|
||||
local -A opts=([-e]="" [-l]="" [-t]="")
|
||||
local i word
|
||||
for (( i = 1; i < cword; i++ )); do
|
||||
word="${words[${i}]}"
|
||||
|
||||
local i
|
||||
for i in "${!words[@]}"; do
|
||||
[[ ${words[i]} && $i -ne $cword ]] && unset -v "opts[${words[i]}]"
|
||||
case "${words[i]}" in
|
||||
-e)
|
||||
unset -v 'opts[-l]' 'opts[-t]'
|
||||
;;
|
||||
-l)
|
||||
unset -v 'opts[-e]' 'opts[-t]'
|
||||
;;
|
||||
-t)
|
||||
unset -v 'opts[-e]' 'opts[-l]'
|
||||
;;
|
||||
esac
|
||||
if [[ "${word:0:1}" == '-' ]]; then # reading an option
|
||||
|
||||
# any option is invalid if...
|
||||
if \
|
||||
(( positional_args > 0 )) || # a positional parameter has been specified \
|
||||
[[ -n "${expected_optarg}" ]] || # a previous option is expecting an argument \
|
||||
! [[ -v valid_opts["${word}"] ]] # the option is invalid given the previously provided ones \
|
||||
then
|
||||
return
|
||||
fi
|
||||
|
||||
local arg_required=${valid_opts["${word}"]}
|
||||
|
||||
case "${word:1}" in
|
||||
a|r)
|
||||
unset -v 'valid_opts[-g]' 'valid_opts[-e]' 'valid_opts[-l]' 'valid_opts[-t]'
|
||||
;;
|
||||
g|e|l|t)
|
||||
valid_opts=()
|
||||
;;
|
||||
*)
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
if ${arg_required}; then
|
||||
expected_optarg="${word}"
|
||||
else
|
||||
expected_optarg=
|
||||
fi
|
||||
|
||||
expected_positional_args=0
|
||||
|
||||
(( opt_args++ ))
|
||||
elif [[ -n "${expected_optarg}" ]]; then
|
||||
expected_optarg=
|
||||
else
|
||||
(( positional_args++ ))
|
||||
|
||||
if (( positional_args > expected_positional_args )); then
|
||||
return
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $cur == -* ]]; then
|
||||
_comp_compgen -- -W '"${!opts[@]}"'
|
||||
if [[ "${cur:0:1}" == '-' ]]; then
|
||||
if [[ -z "${expected_optarg}" ]] && (( positional_args == 0 )); then
|
||||
_comp_compgen -- -W '"${!valid_opts[@]}"'
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
case $prev in
|
||||
-e)
|
||||
[[ -v 'opts[-e]' ]] && __goto_comp_keys
|
||||
return
|
||||
;;
|
||||
esac
|
||||
if [[ "${prev:0:1}" == '-' ]]; then
|
||||
case "${prev:1}" in
|
||||
r|g)
|
||||
__goto_comp_keys
|
||||
;;
|
||||
esac
|
||||
return
|
||||
fi
|
||||
|
||||
# do goto keys only if we did not have -[elt]
|
||||
[[ ${words[*]} == *\ -* ]] || __goto_comp_keys
|
||||
if (( opt_args == 0 && positional_args == 0 )); then
|
||||
__goto_comp_keys
|
||||
fi
|
||||
} &&
|
||||
complete -F _comp_cmd_goto goto
|
||||
|
||||
# ex: filetype=sh
|
||||
# ex: filetype=sh
|
||||
|
||||
Reference in New Issue
Block a user