@@ -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