@@ -735,24 +735,68 @@ _comp_compgen__call_generator()
735735# @arr[in] _upvars
736736# @var[in] _append
737737# @var[in] _var
738- _comp_compgen__call_builtin ()
739- {
740- local _result
741- _result= $(
738+ if (( BASH_VERSINFO[ 0 ] > 5 || BASH_VERSINFO[ 0 ] == 5 && BASH_VERSINFO[ 1 ] >= 3 )) ; then
739+ # bash >= 5.3 has `compgen -V array_name`
740+ _comp_compgen__call_builtin ()
741+ {
742742 if [[ $_dir ]]; then
743+ local _original_pwd=$PWD
744+ local PWD=${PWD-} OLDPWD=${OLDPWD-}
743745 # Note: We also redirect stdout because `cd` may output the target
744746 # directory to stdout when CDPATH is set.
745- command cd -- " $_dir " & > /dev/null || return
747+ command cd -- " $_dir " & > /dev/null || {
748+ _comp_compgen__error_fallback
749+ return
750+ }
751+ fi
752+
753+ local -a _result=()
754+
755+ # Note: We specify -X '' to exclude empty completions to make the
756+ # behavior consistent with the implementation for Bash < 5.3 where
757+ # `_comp_split -l` removes empty lines. If the caller specifies -X
758+ # pat, the effect of -X '' is overwritten by the specified one.
759+ IFS=$_ifs compgen -V _result -X ' ' " $@ " ${_cur: +-- " $_cur " } || {
760+ _comp_compgen__error_fallback
761+ return
762+ }
763+
764+ # Go back to the original directory.
765+ # Note: Failure of this line results in the change of the current
766+ # directory visible to the user. We intentionally do not redirect
767+ # stderr so that the error message appear in the terminal.
768+ # shellcheck disable=SC2164
769+ [[ $_dir ]] && command cd -- " $_original_pwd "
770+
771+ (( ${# _upvars[@]} )) && _comp_unlocal " ${_upvars[@]} "
772+ (( ${# _result[@]} )) || return
773+ if [[ $_append ]]; then
774+ eval -- " $_var +=(\"\$ {_result[@]}\" )"
775+ else
776+ eval -- " $_var =(\"\$ {_result[@]}\" )"
746777 fi
747- IFS=$_ifs compgen " $@ " ${_cur: +-- " $_cur " }
748- ) || {
749- _comp_compgen__error_fallback
750778 return
751779 }
780+ else
781+ _comp_compgen__call_builtin ()
782+ {
783+ local _result
784+ _result=$(
785+ if [[ $_dir ]]; then
786+ # Note: We also redirect stdout because `cd` may output the target
787+ # directory to stdout when CDPATH is set.
788+ command cd -- " $_dir " & > /dev/null || return
789+ fi
790+ IFS=$_ifs compgen " $@ " ${_cur: +-- " $_cur " }
791+ ) || {
792+ _comp_compgen__error_fallback
793+ return
794+ }
752795
753- (( ${# _upvars[@]} )) && _comp_unlocal " ${_upvars[@]} "
754- _comp_split -l ${_append: +-a} " $_var " " $_result "
755- }
796+ (( ${# _upvars[@]} )) && _comp_unlocal " ${_upvars[@]} "
797+ _comp_split -l ${_append: +-a} " $_var " " $_result "
798+ }
799+ fi
756800
757801# usage: _comp_compgen_set [words...]
758802# Reset COMPREPLY with the specified WORDS. If no arguments are specified, the
0 commit comments