@@ -457,11 +457,14 @@ _comp_compgen__error_fallback()
457457# @return True (0) if at least one completion is generated, False (1) if no
458458# completion is generated, or 2 with an incorrect usage.
459459#
460- # Usage #2: _comp_compgen [-aR|-v arr|-c cur|-C dir] name args...
460+ # Usage #2: _comp_compgen [-aR|-v arr|-c cur|-C dir|-i cmd|-x cmd ] name args...
461461# Call the generator `_comp_compgen_NAME ARGS...` with the specified options.
462462# This provides a common interface to call the functions `_comp_compgen_NAME`,
463463# which produce completion candidates, with custom options [-alR|-v arr|-c
464464# cur]. The option `-F sep` is not used with this usage.
465+ # OPTIONS
466+ # -x cmd Call exported generator `_comp_xfunc_CMD_compgen_NAME`
467+ # -i cmd Call internal generator `_comp_cmd_CMD__compgen_NAME`
465468# @param $1... name args Calls the function _comp_compgen_NAME with the
466469# specified ARGS (if $1 does not start with a hyphen `-`). The options
467470# [-alR|-v arr|-c cur] are inherited by the child calls of `_comp_compgen`
@@ -516,7 +519,7 @@ _comp_compgen()
516519 shopt -u nocasematch
517520 fi
518521 local OPTIND=1 OPTARG=" " OPTERR=0 _opt
519- while getopts ' :av:Rc:C:lF:' _opt " $@ " ; do
522+ while getopts ' :av:Rc:C:lF:i:x: ' _opt " $@ " ; do
520523 case $_opt in
521524 a) _append=set ;;
522525 v)
@@ -537,6 +540,20 @@ _comp_compgen()
537540 ;;
538541 l) _has_ifs=set _ifs=$' \n ' ;;
539542 F) _has_ifs=set _ifs=$OPTARG ;;
543+ [ix])
544+ if [[ ! $OPTARG ]]; then
545+ printf ' bash_completion: %s: -%s: invalid command name `%s' \' ' \n' " $FUNCNAME " " $_opt " " $OPTARG " >&2
546+ return 2
547+ elif [[ $_icmd ]]; then
548+ printf ' bash_completion: %s: -%s: `-i %s' \' ' is already specified\n' " $FUNCNAME " " $_opt " " $_icmd " >&2
549+ return 2
550+ elif [[ $_xcmd ]]; then
551+ printf ' bash_completion: %s: -%s: `-x %s' \' ' is already specified\n' " $FUNCNAME " " $_opt " " $_xcmd " >&2
552+ return 2
553+ fi
554+ ;;&
555+ i) _icmd=$OPTARG ;;
556+ x) _xcmd=$OPTARG ;;
540557 * )
541558 printf ' bash_completion: %s: usage error\n' " $FUNCNAME " >&2
542559 return 2
@@ -558,8 +575,16 @@ _comp_compgen()
558575 return 2
559576 fi
560577
561- if ! declare -F " _comp_compgen_$1 " & > /dev/null; then
562- printf ' bash_completion: %s: unrecognized category `%s' \' ' (function _comp_compgen_%s not found)\n' " $FUNCNAME " " $1 " " $1 " >&2
578+ local -a _generator
579+ if [[ $_icmd ]]; then
580+ _generator=(" _comp_cmd_${_icmd// [^a-zA-Z0-9_]/ _} __compgen_$1 " )
581+ elif [[ $_xcmd ]]; then
582+ _generator=(_comp_xfunc " $_xcmd " " compgen_$1 " )
583+ else
584+ _generator=(" _comp_compgen_$1 " )
585+ fi
586+ if ! declare -F " ${_generator[0]} " & > /dev/null; then
587+ printf ' bash_completion: %s: unrecognized generator `%s' \' ' (function %s not found)\n' " $FUNCNAME " " $1 " " ${_generator[0]} " >&2
563588 return 2
564589 fi
565590
@@ -581,7 +606,7 @@ _comp_compgen()
581606 # Note: we use $1 as a part of a function name, and we use $2... as
582607 # arguments to the function if any.
583608 # shellcheck disable=SC2145
584- _comp_compgen_ " $@ "
609+ " ${_generator[@]} " " ${ @: 2} "
585610 local _status=$?
586611
587612 # Go back to the original directory.
@@ -595,6 +620,10 @@ _comp_compgen()
595620 fi
596621
597622 # usage: _comp_compgen [options] -- [compgen_options]
623+ if [[ $_icmd || $_xcmd ]]; then
624+ printf ' bash_completion: %s: generator name is unspecified for `%s' \' ' \n' " $FUNCNAME " " ${_icmd: +-i $_icmd }${_xcmd: +x $_xcmd } " >&2
625+ return 2
626+ fi
598627
599628 # Note: $* in the below checks would be affected by uncontrolled IFS in
600629 # bash >= 5.0, so we need to set IFS to the normal value. The behavior in
0 commit comments