@@ -320,7 +320,7 @@ _comp_upvars()
320320# interference from user's shell options/settings or environment variables.
321321# @param $1 array_name Array name
322322# The array name should not start with an underscore "_", which is internally
323- # used. The array name should not be "GLOBIGNORE".
323+ # used. The array name should not be "GLOBIGNORE" or "GLOBSORT" .
324324# @param $2 pattern Pattern string to be evaluated.
325325# This pattern string will be evaluated using "eval", so brace expansions,
326326# parameter expansions, command substitutions, and other expansions will be
@@ -335,7 +335,7 @@ _comp_expand_glob()
335335 printf ' bash-completion: %s: unexpected number of arguments\n' " $FUNCNAME " >&2
336336 printf ' usage: %s ARRAY_NAME PATTERN\n' " $FUNCNAME " >&2
337337 return 2
338- elif [[ $1 == @ (GLOBIGNORE| _* | * [^_a-zA-Z0-9]* | [0-9]* | ' ' ) ]]; then
338+ elif [[ $1 == @ (GLOBIGNORE| GLOBSORT | _* | * [^_a-zA-Z0-9]* | [0-9]* | ' ' ) ]]; then
339339 printf ' bash-completion: %s: invalid array name "%s"\n' " $FUNCNAME " " $1 " >&2
340340 return 2
341341 fi
@@ -346,8 +346,13 @@ _comp_expand_glob()
346346 shopt -s nullglob
347347 shopt -u failglob dotglob
348348
349- # Also the user's GLOBIGNORE may affect the result of pathname expansions.
350- local GLOBIGNORE=
349+ # Also the user's GLOBIGNORE and GLOBSORT (bash >= 5.3) may affect the
350+ # result of pathname expansions.
351+ local GLOBIGNORE=" " GLOBSORT=name
352+
353+ # To canonicalize the sorting order of the generated paths, we set
354+ # LC_COLLATE=C and unset LC_ALL while preserving LC_CTYPE.
355+ local LC_COLLATE=C LC_CTYPE=${LC_ALL:- ${LC_CTYPE:- ${LANG-} } } LC_ALL=
351356
352357 eval -- " $1 =()" # a fallback in case that the next line fails.
353358 eval -- " $1 =($2 )"
@@ -3298,45 +3303,65 @@ else
32983303 }
32993304fi
33003305
3301- # source compat completion directory definitions
3302- _comp__init_compat_dirs=()
3303- if [[ ${BASH_COMPLETION_COMPAT_DIR-} ]]; then
3304- _comp__init_compat_dirs+=(" $BASH_COMPLETION_COMPAT_DIR " )
3305- else
3306- _comp__init_compat_dirs+=(/etc/bash_completion.d)
3307- # Similarly as for the "completions" dir, look up from relative to
3308- # bash_completion, primarily for installed-with-prefix and
3309- # run-in-place-from-git-clone setups. Notably we do it after the system
3310- # location here, in order to prefer in-tree variables and functions.
3311- if [[ ${BASH_SOURCE%/* } == * /share/bash-completion ]]; then
3312- _comp__init_compat_dir=${BASH_SOURCE%/ share/ bash-completion/* } /etc/bash_completion.d
3313- elif [[ $BASH_SOURCE == * /* ]]; then
3314- _comp__init_compat_dir=" ${BASH_SOURCE%/* } /bash_completion.d"
3306+ # List custom/extra completion files to source on the startup
3307+ # # @param $1 path Path to "bash_completion"
3308+ # # @var[out] _comp__init_startup_configs
3309+ _comp__init_collect_startup_configs ()
3310+ {
3311+ local base_path=${1:- ${BASH_SOURCE[1]} }
3312+ _comp__init_startup_configs=()
3313+
3314+ # source compat completion directory definitions
3315+ local -a compat_dirs=()
3316+ local compat_dir
3317+ if [[ ${BASH_COMPLETION_COMPAT_DIR-} ]]; then
3318+ compat_dirs+=(" $BASH_COMPLETION_COMPAT_DIR " )
33153319 else
3316- _comp__init_compat_dir=./bash_completion.d
3317- fi
3318- [[ ${_comp__init_compat_dirs[0]} == " $_comp__init_compat_dir " ]] ||
3319- _comp__init_compat_dirs+=(" $_comp__init_compat_dir " )
3320- fi
3321- for _comp__init_compat_dir in " ${_comp__init_compat_dirs[@]} " ; do
3322- [[ -d $_comp__init_compat_dir && -r $_comp__init_compat_dir && -x $_comp__init_compat_dir ]] || continue
3323- for _comp__init_file in " $_comp__init_compat_dir " /* ; do
3324- [[ ${_comp__init_file##*/ } != @ ($_comp_backup_glob | Makefile* | ${BASH_COMPLETION_COMPAT_IGNORE-} ) &&
3325- -f $_comp__init_file && -r $_comp__init_file ]] && . " $_comp__init_file "
3320+ compat_dirs+=(/etc/bash_completion.d)
3321+ # Similarly as for the "completions" dir, look up from relative to
3322+ # bash_completion, primarily for installed-with-prefix and
3323+ # run-in-place-from-git-clone setups. Notably we do it after the
3324+ # system location here, in order to prefer in-tree variables and
3325+ # functions.
3326+ if [[ ${base_path%/* } == * /share/bash-completion ]]; then
3327+ compat_dir=${base_path%/ share/ bash-completion/* } /etc/bash_completion.d
3328+ elif [[ $base_path == * /* ]]; then
3329+ compat_dir=" ${base_path%/* } /bash_completion.d"
3330+ else
3331+ compat_dir=./bash_completion.d
3332+ fi
3333+ [[ ${compat_dirs[0]} == " $compat_dir " ]] ||
3334+ compat_dirs+=(" $compat_dir " )
3335+ fi
3336+ for compat_dir in " ${compat_dirs[@]} " ; do
3337+ [[ -d $compat_dir && -r $compat_dir && -x $compat_dir ]] || continue
3338+ local compat_files
3339+ _comp_expand_glob compat_files ' "$compat_dir"/*'
3340+ local compat_file
3341+ for compat_file in " ${compat_files[@]} " ; do
3342+ [[ ${compat_file##*/ } != @ ($_comp_backup_glob | Makefile* | ${BASH_COMPLETION_COMPAT_IGNORE-} ) &&
3343+ -f $compat_file && -r $compat_file ]] &&
3344+ _comp__init_startup_configs+=(" $compat_file " )
3345+ done
33263346 done
3327- done
3328- unset -v _comp__init_compat_dirs _comp__init_compat_dir _comp__init_file
33293347
3330- # source user completion file
3331- #
3332- # Remark: We explicitly check that $user_completion is not '/dev/null' since
3333- # /dev/null may be a regular file in broken systems and can contain arbitrary
3334- # garbages of suppressed command outputs.
3335- _comp__init_user_file=${BASH_COMPLETION_USER_FILE:- ~/ .bash_completion}
3336- [[ $_comp__init_user_file != " ${BASH_SOURCE[0]} " && $_comp__init_user_file != /dev/null && -r $_comp__init_user_file && -f $_comp__init_user_file ]] &&
3337- . " $_comp__init_user_file "
3338- unset -v _comp__init_user_file
3348+ # source user completion file
3349+ #
3350+ # Remark: We explicitly check that $user_completion is not '/dev/null'
3351+ # since /dev/null may be a regular file in broken systems and can contain
3352+ # arbitrary garbages of suppressed command outputs.
3353+ local user_file=${BASH_COMPLETION_USER_FILE:- ~/ .bash_completion}
3354+ [[ $user_file != " $base_path " && $user_file != /dev/null && -r $user_file && -f $user_file ]] &&
3355+ _comp__init_startup_configs+=(" $user_file " )
33393356
3357+ unset -f " $FUNCNAME "
3358+ }
3359+ _comp__init_collect_startup_configs " $BASH_SOURCE "
3360+ # shellcheck disable=SC2154
3361+ for _comp_init_startup_config in " ${_comp__init_startup_configs[@]} " ; do
3362+ . " $_comp_init_startup_config "
3363+ done
3364+ unset -v _comp__init_startup_configs _comp_init_startup_config
33403365unset -f have
33413366unset -v have
33423367
0 commit comments