Skip to content

Commit 9ad6f8f

Browse files
committed
refactor(_comp_compgen): separate the builtin and generator calls
1 parent 6f03827 commit 9ad6f8f

File tree

1 file changed

+73
-46
lines changed

1 file changed

+73
-46
lines changed

bash_completion

Lines changed: 73 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -655,61 +655,88 @@ _comp_compgen()
655655
printf 'bash_completion: %s: unrecognized generator `%s'\'' (function %s not found)\n' "$FUNCNAME" "$1" "${_generator[0]}" >&2
656656
return 2
657657
fi
658+
shift
658659

659-
((${#_upvars[@]})) && _comp_unlocal "${_upvars[@]}"
660+
_comp_compgen__call_generator "$@"
661+
else
662+
# usage: _comp_compgen [options] -- [compgen_options]
663+
if [[ $_icmd || $_xcmd ]]; then
664+
printf 'bash_completion: %s: generator name is unspecified for `%s'\''\n' "$FUNCNAME" "${_icmd:+-i $_icmd}${_xcmd:+x $_xcmd}" >&2
665+
return 2
666+
fi
660667

661-
if [[ $_dir ]]; then
662-
local _original_pwd=$PWD
663-
local PWD=${PWD-} OLDPWD=${OLDPWD-}
664-
# Note: We also redirect stdout because `cd` may output the target
665-
# directory to stdout when CDPATH is set.
666-
command cd -- "$_dir" &>/dev/null ||
667-
{
668-
_comp_compgen__error_fallback
669-
return
670-
}
668+
# Note: $* in the below checks would be affected by uncontrolled IFS in
669+
# bash >= 5.0, so we need to set IFS to the normal value. The behavior
670+
# in bash < 5.0, where unquoted $* in conditional command did not honor
671+
# IFS, was a bug.
672+
# Note: Also, ${_cur:+-- "$_cur"} and ${_append:+-a} would be affected
673+
# by uncontrolled IFS.
674+
local IFS=$' \t\n'
675+
# Note: extglob *\$?(\{)[0-9]* can be extremely slow when the string
676+
# "${*:2:_nopt}" becomes longer, so we test \$[0-9] and \$\{[0-9]
677+
# separately.
678+
if [[ $* == *\$[0-9]* || $* == *\$\{[0-9]* ]]; then
679+
printf 'bash_completion: %s: positional parameter $1, $2, ... do not work inside this function\n' "$FUNCNAME" >&2
680+
return 2
671681
fi
672682

673-
local _comp_compgen__append=$_append
674-
local _comp_compgen__var=$_var
675-
local _comp_compgen__cur=$_cur cur=$_cur
676-
# Note: we use $1 as a part of a function name, and we use $2... as
677-
# arguments to the function if any.
678-
# shellcheck disable=SC2145
679-
"${_generator[@]}" "${@:2}"
680-
local _status=$?
683+
_comp_compgen__call_builtin "$@"
684+
fi
685+
}
681686

682-
# Go back to the original directory.
683-
# Note: Failure of this line results in the change of the current
684-
# directory visible to the user. We intentionally do not redirect
685-
# stderr so that the error message appear in the terminal.
686-
# shellcheck disable=SC2164
687-
[[ $_dir ]] && command cd -- "$_original_pwd"
687+
# Helper function for _comp_compgen. This function calls a generator.
688+
# @param $1... generator_args
689+
# @var[in] _dir
690+
# @var[in] _cur
691+
# @arr[in] _generator
692+
# @arr[in] _upvars
693+
# @var[in] _append
694+
# @var[in] _var
695+
_comp_compgen__call_generator()
696+
{
697+
((${#_upvars[@]})) && _comp_unlocal "${_upvars[@]}"
688698

689-
return "$_status"
690-
fi
699+
if [[ $_dir ]]; then
700+
local _original_pwd=$PWD
701+
local PWD=${PWD-} OLDPWD=${OLDPWD-}
702+
# Note: We also redirect stdout because `cd` may output the target
703+
# directory to stdout when CDPATH is set.
704+
command cd -- "$_dir" &>/dev/null ||
705+
{
706+
_comp_compgen__error_fallback
707+
return
708+
}
709+
fi
710+
711+
local _comp_compgen__append=$_append
712+
local _comp_compgen__var=$_var
713+
local _comp_compgen__cur=$_cur cur=$_cur
714+
# Note: we use $1 as a part of a function name, and we use $2... as
715+
# arguments to the function if any.
716+
# shellcheck disable=SC2145
717+
"${_generator[@]}" "$@"
718+
local _status=$?
691719

692-
# usage: _comp_compgen [options] -- [compgen_options]
693-
if [[ $_icmd || $_xcmd ]]; then
694-
printf 'bash_completion: %s: generator name is unspecified for `%s'\''\n' "$FUNCNAME" "${_icmd:+-i $_icmd}${_xcmd:+x $_xcmd}" >&2
695-
return 2
696-
fi
720+
# Go back to the original directory.
721+
# Note: Failure of this line results in the change of the current
722+
# directory visible to the user. We intentionally do not redirect
723+
# stderr so that the error message appear in the terminal.
724+
# shellcheck disable=SC2164
725+
[[ $_dir ]] && command cd -- "$_original_pwd"
697726

698-
# Note: $* in the below checks would be affected by uncontrolled IFS in
699-
# bash >= 5.0, so we need to set IFS to the normal value. The behavior in
700-
# bash < 5.0, where unquoted $* in conditional command did not honor IFS,
701-
# was a bug.
702-
# Note: Also, ${_cur:+-- "$_cur"} and ${_append:+-a} would be affected by
703-
# uncontrolled IFS.
704-
local IFS=$' \t\n'
705-
# Note: extglob *\$?(\{)[0-9]* can be extremely slow when the string
706-
# "${*:2:_nopt}" becomes longer, so we test \$[0-9] and \$\{[0-9]
707-
# separately.
708-
if [[ $* == *\$[0-9]* || $* == *\$\{[0-9]* ]]; then
709-
printf 'bash_completion: %s: positional parameter $1, $2, ... do not work inside this function\n' "$FUNCNAME" >&2
710-
return 2
711-
fi
727+
return "$_status"
728+
}
712729

730+
# Helper function for _comp_compgen. This function calls the builtin compgen.
731+
# @param $1... compgen_args
732+
# @var[in] _dir
733+
# @var[in] _ifs
734+
# @var[in] _cur
735+
# @arr[in] _upvars
736+
# @var[in] _append
737+
# @var[in] _var
738+
_comp_compgen__call_builtin()
739+
{
713740
local _result
714741
_result=$(
715742
if [[ $_dir ]]; then

0 commit comments

Comments
 (0)