@@ -320,7 +320,7 @@ _comp_upvars()
320
320
# interference from user's shell options/settings or environment variables.
321
321
# @param $1 array_name Array name
322
322
# 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" .
324
324
# @param $2 pattern Pattern string to be evaluated.
325
325
# This pattern string will be evaluated using "eval", so brace expansions,
326
326
# parameter expansions, command substitutions, and other expansions will be
@@ -335,7 +335,7 @@ _comp_expand_glob()
335
335
printf ' bash-completion: %s: unexpected number of arguments\n' " $FUNCNAME " >&2
336
336
printf ' usage: %s ARRAY_NAME PATTERN\n' " $FUNCNAME " >&2
337
337
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
339
339
printf ' bash-completion: %s: invalid array name "%s"\n' " $FUNCNAME " " $1 " >&2
340
340
return 2
341
341
fi
@@ -346,8 +346,13 @@ _comp_expand_glob()
346
346
shopt -s nullglob
347
347
shopt -u failglob dotglob
348
348
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=
351
356
352
357
eval -- " $1 =()" # a fallback in case that the next line fails.
353
358
eval -- " $1 =($2 )"
@@ -3298,45 +3303,65 @@ else
3298
3303
}
3299
3304
fi
3300
3305
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 " )
3315
3319
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
3326
3346
done
3327
- done
3328
- unset -v _comp__init_compat_dirs _comp__init_compat_dir _comp__init_file
3329
3347
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 " )
3339
3356
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
3340
3365
unset -f have
3341
3366
unset -v have
3342
3367
0 commit comments