Skip to content

Commit

Permalink
Merge pull request #1036 from akinomyoga/refactor-api-5
Browse files Browse the repository at this point in the history
refactor: refactor `_comp_{get_first_word,count_args}`
  • Loading branch information
scop committed Sep 12, 2023
2 parents 349ac51 + 3127703 commit 0661fb5
Show file tree
Hide file tree
Showing 16 changed files with 170 additions and 77 deletions.
87 changes: 71 additions & 16 deletions bash_completion
Original file line number Diff line number Diff line change
Expand Up @@ -2159,46 +2159,101 @@ _comp_realcommand()
fi
}

# This function returns the first argument, excluding options
# @var[out] ret First argument before current being completed if any, or
# otherwise an empty string
# This function returns the position of the first argument, excluding options
#
# Options:
# -a GLOB Pattern of options that take an option argument
#
# @var[out] ret Position of the first argument before the current one being
# completed if any, or otherwise an empty string
# @return True (0) if any argument is found, False (> 0) otherwise.
# @since 2.12
_comp_get_first_arg()
_comp_locate_first_arg()
{
local i
local has_optarg=""
local OPTIND=1 OPTARG="" OPTERR=0 _opt
while getopts ':a:' _opt "$@"; do
case $_opt in
a) has_optarg=$OPTARG ;;
*)
echo "bash_completion: $FUNCNAME: usage error" >&2
return 2
;;
esac
done
shift "$((OPTIND - 1))"

local i
ret=
for ((i = 1; i < cword; i++)); do
if [[ ${words[i]} != -?* ]]; then
ret=${words[i]}
# shellcheck disable=SC2053
if [[ $has_optarg && ${words[i]} == $has_optarg ]]; then
((i++))
elif [[ ${words[i]} != -?* ]]; then
ret=$i
return 0
elif [[ ${words[i]} == -- ]]; then
((i + 1 < cword)) && ret=${words[i + 1]} && return 0
((i + 1 < cword)) && ret=$((i + 1)) && return 0
break
fi
done
return 1
}

# This function returns the first argument, excluding options
#
# Options:
# -a GLOB Pattern of options that take an option argument
#
# @var[out] ret First argument before the current one being completed if any,
# or otherwise an empty string
# @return True (0) if any argument is found, False (> 0) otherwise.
# @since 2.12
_comp_get_first_arg()
{
_comp_locate_first_arg "$@" && ret=${words[ret]}
}

# This function counts the number of args, excluding options
# @param $1 chars Characters out of $COMP_WORDBREAKS which should
# NOT be considered word breaks. See _comp__reassemble_words.
# @param $2 glob Options whose following argument should not be counted
# @param $3 glob Options that should be counted as args
#
# Options:
# -n CHARS Characters out of $COMP_WORDBREAKS which should
# NOT be considered word breaks. See
# _comp__reassemble_words.
# -a GLOB Options whose following argument should not be counted
# -i GLOB Options that should be counted as args
#
# @var[out] ret Return the number of arguments
# @since 2.12
_comp_count_args()
{
local i cword words
_comp__reassemble_words "${1-}" words cword
local has_optarg="" has_exclude="" exclude="" glob_include=""
local OPTIND=1 OPTARG="" OPTERR=0 _opt
while getopts ':a:n:i:' _opt "$@"; do
case $_opt in
a) has_optarg=$OPTARG ;;
n) has_exclude=set exclude+=$OPTARG ;;
i) glob_include=$OPTARG ;;
*)
echo "bash_completion: $FUNCNAME: usage error" >&2
return 2
;;
esac
done
shift "$((OPTIND - 1))"

if [[ $has_exclude ]]; then
local cword words
_comp__reassemble_words "$exclude<>&" words cword
fi

local i
ret=1
for ((i = 1; i < cword; i++)); do
# shellcheck disable=SC2053
if [[ ${2-} && ${words[i]} == ${2-} ]]; then
if [[ $has_optarg && ${words[i]} == $has_optarg ]]; then
((i++))
elif [[ ${words[i]} != -?* || ${3-} && ${words[i]} == ${3-} ]]; then
elif [[ ${words[i]} != -?* || $glob_include && ${words[i]} == $glob_include ]]; then
((ret++))
elif [[ ${words[i]} == -- ]]; then
((ret += cword - i - 1))
Expand Down
2 changes: 1 addition & 1 deletion completions/7z
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ _comp_cmd_7z()
fi

local ret
_comp_count_args "="
_comp_count_args
if ((ret == 2)); then
_filedir_xspec unzip "${@:2}"
# TODO: parsing 7z i output?
Expand Down
2 changes: 1 addition & 1 deletion completions/arp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ _comp_cmd_arp()
fi

local ret
_comp_count_args "" "@(--device|--protocol|--file|--hw-type|-${noargopts}[iApfHt])"
_comp_count_args -a "@(--device|--protocol|--file|--hw-type|-${noargopts}[iApfHt])"
case $ret in
1)
local ips=$("$1" -an | command sed -ne \
Expand Down
2 changes: 1 addition & 1 deletion completions/chmod
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ _comp_cmd_chmod()
fi

local ret
_comp_count_args "" "" "$modearg"
_comp_count_args -i "$modearg"

case $ret in
1) ;; # mode
Expand Down
2 changes: 1 addition & 1 deletion completions/chown
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ _comp_cmd_chown()
local ret

# The first argument is a usergroup; the rest are filedir.
_comp_count_args :
_comp_count_args

if ((ret == 1)); then
_comp_compgen_usergroups -u
Expand Down
2 changes: 1 addition & 1 deletion completions/cryptsetup
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ _comp_cmd_cryptsetup()
local ret
if _comp_get_first_arg; then
local arg=$ret
_comp_count_args "" "-${noargopts}[chslSbopitTdM]"
_comp_count_args -a "-${noargopts}[chslSbopitTdM]"
local args=$ret
case $arg in
open | create | luksOpen | loopaesOpen | tcryptOpen)
Expand Down
2 changes: 1 addition & 1 deletion completions/gpgv
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ _comp_cmd_gpgv()
esac

local ret
_comp_count_args "" "--@(weak-digest|*-fd|keyring|homedir)"
_comp_count_args -a "--@(weak-digest|*-fd|keyring|homedir)"
local args=$ret

if [[ $cur == -* && $args -eq 1 ]]; then
Expand Down
2 changes: 1 addition & 1 deletion completions/ifup
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ _comp_cmd_ifupdown()
fi

local ret
_comp_count_args "" "@(--allow|-i|--interfaces|--state-dir|-X|--exclude|-o)"
_comp_count_args -a "@(--allow|-i|--interfaces|--state-dir|-X|--exclude|-o)"

if ((ret == 1)); then
_comp_compgen_configured_interfaces
Expand Down
2 changes: 1 addition & 1 deletion completions/jq
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ _comp_cmd_jq()
local ret
# TODO: DTRT with args taking 2 options
# -f|--from-file are not counted here because they supply the filter
_comp_count_args "" "@(--arg|--arg?(json|file)|--slurpfile|--indent|--run-tests|-${noargopts}L)"
_comp_count_args -a "@(--arg|--arg?(json|file)|--slurpfile|--indent|--run-tests|-${noargopts}L)"

# 1st arg is filter
((ret == 1)) && return
Expand Down
2 changes: 1 addition & 1 deletion completions/jsonschema
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ _comp_cmd_jsonschema()
fi

local ret
_comp_count_args "" "-*"
_comp_count_args -a "-*"
((ret == 1)) || return
_comp_compgen_filedir '@(json|schema)'
} &&
Expand Down
2 changes: 1 addition & 1 deletion completions/nc
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ _comp_cmd_nc()

# Complete 1st non-option arg only
local ret
_comp_count_args "" "-*[IiMmOPpqsTVWwXx]"
_comp_count_args -n "" -a "-*[IiMmOPpqsTVWwXx]"
((ret == 1)) || return

_known_hosts_real -- "$cur"
Expand Down
4 changes: 2 additions & 2 deletions completions/nslookup
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ _comp_cmd_nslookup()
fi

local ret
_comp_count_args "="
_comp_count_args
if ((ret <= 2)); then
_known_hosts_real -- "$cur"
[[ $ret -eq 1 && $cur == @(|-) ]] && COMPREPLY+=(-)
Expand Down Expand Up @@ -90,7 +90,7 @@ _comp_cmd_host()
fi

local ret
_comp_count_args "" "-*[ctmNRW]"
_comp_count_args -a "-*[ctmNRW]"
if ((ret == 1)); then
_known_hosts_real -- "$cur"
elif ((ret == 2)); then
Expand Down
2 changes: 1 addition & 1 deletion completions/sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ _comp_cmd_sh()
fi

local ret ext=
_comp_count_args "" "@(-c|[-+]o)"
_comp_count_args -a "@(-c|[-+]o)"
((ret == 1)) && ext="sh"
_comp_compgen_filedir $ext
} &&
Expand Down
2 changes: 1 addition & 1 deletion completions/ssh
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ _comp_cmd_ssh()
else
local ret
# Keep glob sort in sync with cases above
_comp_count_args "=" "-*[BbcDeLpRWEFSIiJlmOoQw]"
_comp_count_args -n "=" -a "-*[BbcDeLpRWEFSIiJlmOoQw]"
if ((ret > 1)); then
compopt -o filenames
_comp_compgen_commands
Expand Down
Loading

0 comments on commit 0661fb5

Please sign in to comment.