@@ -3372,6 +3372,58 @@ _comp__init_base_directory()
33723372}
33733373_comp__init_base_directory
33743374
3375+ # Attempt to load the specified file and check if the completion setting is
3376+ # successfully loaded.
3377+ #
3378+ # @param $1 compfile ... filename to check.
3379+ # @var[in] cmdname
3380+ # @var[in] cmd
3381+ # @var[in] backslash
3382+ # @var[in] origcmd
3383+ # @var[in] source_args
3384+ # @exit 0 when the file is found, and the completion setting was successfully
3385+ # loaded. Otherwise, 1.
3386+ _comp_load__visit_file()
3387+ {
3388+ local compfile=$1
3389+ shift
3390+ [[ -e $compfile ]] || return 1
3391+
3392+ # Set up default $IFS in case loaded completions depend on it, as well as
3393+ # for $compspec invocation below.
3394+ local IFS=$' \t\n' compspec
3395+
3396+ # Avoid trying to source dirs as long as we support bash < 4.3
3397+ # to avoid an fd leak; https://bugzilla.redhat.com/903540
3398+ if [[ -d $compfile ]]; then
3399+ # Do not warn with . or .. (especially the former is common)
3400+ [[ $compfile == */.?(.) ]] ||
3401+ echo " bash_completion: $compfile : is a directory" >&2
3402+ elif . " $compfile " " $cmd " ${source_args[@]+" ${source_args[@]} " } ; then
3403+
3404+ # At least $cmd is expected to have a completion set when we return
3405+ # successfully; see if it already does
3406+ if compspec=$( complete -p -- " $cmd " 2> /dev/null) ; then
3407+ # $cmd is the case in which we do backslash processing
3408+ [[ $backslash ]] && eval " $compspec \"\$ backslash\$ cmd\" "
3409+ # If invoked without path, that one should be set, too
3410+ # ...but let's not overwrite an existing one, if any
3411+ [[ $origcmd != */* ]] &&
3412+ ! complete -p -- " $origcmd " &>/dev/null &&
3413+ eval " $compspec \"\$ origcmd\" "
3414+ return 0
3415+ fi
3416+ # If not, see if we got one for $cmdname
3417+ if [[ $cmdname != " $cmd " ]] && compspec=$( complete -p -- " $cmdname " 2> /dev/null) ; then
3418+ # Use that for $cmd too, if we have a full path to it
3419+ [[ $cmd == /* ]] && eval " $compspec \"\$ cmd\" "
3420+ return 0
3421+ fi
3422+ # Nothing expected was set, continue lookup
3423+ fi
3424+ return 1
3425+ }
3426+
33753427# @since 2.12
33763428_comp_load()
33773429{
@@ -3413,18 +3465,17 @@ _comp_load()
34133465 # 1) From BASH_COMPLETION_USER_DIR (e.g. ~/.local/share/bash-completion):
34143466 # User installed completions.
34153467 if [[ ${BASH_COMPLETION_USER_DIR-} ]]; then
3416- _comp_split -F : paths " $BASH_COMPLETION_USER_DIR " &&
3417- dirs+=(" ${paths[@]/%// completions} " )
3468+ _comp_split -F : dirs " $BASH_COMPLETION_USER_DIR "
34183469 else
3419- dirs=(" ${XDG_DATA_HOME:- $HOME / .local/ share} /bash-completion/completions " )
3470+ dirs=(" ${XDG_DATA_HOME:- $HOME / .local/ share} /bash-completion" )
34203471 fi
34213472
34223473 # 2) From the location of bash_completion: Completions relative to the main
34233474 # script. This is primarily for run-in-place-from-git-clone setups, where
34243475 # we want to prefer in-tree completions over ones possibly coming with a
34253476 # system installed bash-completion. (Due to usual install layouts, this
34263477 # often hits the correct completions in system installations, too.)
3427- dirs+=(" $_comp__base_directory /completions " )
3478+ dirs+=(" $_comp__base_directory " )
34283479
34293480 # 3) From bin directories extracted from the specified path to the command,
34303481 # the real path to the command, and $PATH
@@ -3434,60 +3485,30 @@ _comp_load()
34343485 _comp_split -aF : paths " $PATH "
34353486 for dir in " ${paths[@]%/ } " ; do
34363487 [[ $dir == ?*/@(bin|sbin) ]] &&
3437- dirs+=(" ${dir%/* } /share/bash-completion/completions " )
3488+ dirs+=(" ${dir%/* } /share/bash-completion" )
34383489 done
34393490
34403491 # 4) From XDG_DATA_DIRS or system dirs (e.g. /usr/share, /usr/local/share):
34413492 # Completions in the system data dirs.
34423493 _comp_split -F : paths " ${XDG_DATA_DIRS:-/ usr/ local/ share:/ usr/ share} " &&
3443- dirs+=(" ${paths[@]/%// bash-completion/ completions} " )
3444-
3445- # Set up default $IFS in case loaded completions depend on it,
3446- # as well as for $compspec invocation below.
3447- local IFS=$' \t\n'
3494+ dirs+=(" ${paths[@]/%// bash-completion} " )
34483495
34493496 # Look up and source
34503497 shift
3451- local i prefix compspec
3498+ local -a source_args=(" $@ " )
3499+
3500+ local i prefix
34523501 for prefix in " " _; do # Regular from all dirs first, then fallbacks
3453- for i in ${! dirs[*]} ; do
3454- dir=${dirs[i]}
3455- if [[ ! -d $dir ]]; then
3456- unset -v 'dirs[i]'
3457- continue
3458- fi
3502+ for i in " ${! dirs[@]} " ; do
3503+ dir=${dirs[i]} /completions
3504+ [[ -d $dir ]] || continue
34593505 for compfile in " $prefix$cmdname " " $prefix$cmdname .bash" ; do
3460- compfile=" $dir /$compfile "
3461- # Avoid trying to source dirs as long as we support bash < 4.3
3462- # to avoid an fd leak; https://bugzilla.redhat.com/903540
3463- if [[ -d $compfile ]]; then
3464- # Do not warn with . or .. (especially the former is common)
3465- [[ $compfile == */.?(.) ]] ||
3466- echo " bash_completion: $compfile : is a directory" >&2
3467- elif [[ -e $compfile ]] && . " $compfile " " $cmd " " $@ " ; then
3468- # At least $cmd is expected to have a completion set when
3469- # we return successfully; see if it already does
3470- if compspec=$( complete -p -- " $cmd " 2> /dev/null) ; then
3471- # $cmd is the case in which we do backslash processing
3472- [[ $backslash ]] && eval " $compspec \"\$ backslash\$ cmd\" "
3473- # If invoked without path, that one should be set, too
3474- # ...but let's not overwrite an existing one, if any
3475- [[ $origcmd != */* ]] &&
3476- ! complete -p -- " $origcmd " &>/dev/null &&
3477- eval " $compspec \"\$ origcmd\" "
3478- return 0
3479- fi
3480- # If not, see if we got one for $cmdname
3481- if [[ $cmdname != " $cmd " ]] && compspec=$( complete -p -- " $cmdname " 2> /dev/null) ; then
3482- # Use that for $cmd too, if we have a full path to it
3483- [[ $cmd == /* ]] && eval " $compspec \"\$ cmd\" "
3484- return 0
3485- fi
3486- # Nothing expected was set, continue lookup
3487- fi
3506+ _comp_load__visit_file " $dir /$compfile " && return 0
34883507 done
34893508 done
34903509 done
3510+ _comp_load__visit_file " $_comp__base_directory /completions-core/$cmdname .bash" && return 0
3511+ _comp_load__visit_file " $_comp__base_directory /completions-fallback/$cmdname .bash" && return 0
34913512
34923513 # Look up simple " xspec" completions
34933514 [[ -v _comp_xspecs[$cmdname ] || -v _xspecs[$cmdname ] ]] &&
0 commit comments