# goto completion -*- shell-script -*- _comp_cmd_goto() { local cur prev words cword comp_args _comp_initialize -- "$@" || return # 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 i word for (( i = 1; i < cword; i++ )); do word="${words[${i}]}" 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:0:1}" == '-' ]]; then if [[ -z "${expected_optarg}" ]] && (( positional_args == 0 )); then _comp_compgen -- -W '"${!valid_opts[@]}"' fi return fi if [[ "${prev:0:1}" == '-' ]]; then case "${prev:1}" in r|g) __goto_comp_keys ;; esac return fi if (( opt_args == 0 && positional_args == 0 )); then __goto_comp_keys fi } && complete -F _comp_cmd_goto goto # ex: filetype=sh