@@ -1093,9 +1093,15 @@ _comp_quote_compgen()
10931093
10941094# This function performs file and directory completion. It's better than
10951095# simply using 'compgen -f', because it honours spaces in filenames.
1096- # @param $1 If `-d', complete only on directories. Otherwise filter/pick only
1097- # completions with `.$1' and the uppercase version of it as file
1098- # extension.
1096+ # @param $1 Complete filenames matching `.$1' and the uppercase version of it.
1097+ # Ignored with `-d`.
1098+ # OPTIONS
1099+ # -d Complete only on directories
1100+ # -f Perform `compopt -f filenames` modifications manually. This
1101+ # suffixes a slash to a directory name. This can be combined with
1102+ # the `-C dir` option to `_comp_compgen`, where the generated
1103+ # filenames do not exist in the current working directory and Bash
1104+ # fails to properly detect the filenames.
10991105# @return 0 if at least one completion is generated, or 1 otherwise.
11001106#
11011107# @since 2.12
@@ -1104,9 +1110,22 @@ _comp_compgen_filedir()
11041110 _comp_compgen_tilde && return
11051111
11061112 local -a toks
1113+ local _dir=" " _filenames=" "
1114+ local OPTIND=1 OPTARG=" " OPTERR=0 _opt
1115+ while getopts " :df" _opt " $@ " ; do
1116+ case $_opt in
1117+ d) _dir=set ;;
1118+ f) _filenames=set ;;
1119+ * )
1120+ printf " bash_completion: %s: usage error\n" " $FUNCNAME " >&2
1121+ return 2
1122+ ;;
1123+ esac
1124+ done
1125+ shift " $(( OPTIND - 1 )) "
11071126 local _arg=${1-}
11081127
1109- if [[ $_arg == -d ]]; then
1128+ if [[ $_dir ]]; then
11101129 _comp_compgen -v toks -- -d
11111130 else
11121131 local REPLY
@@ -1141,9 +1160,19 @@ _comp_compgen_filedir()
11411160 fi
11421161
11431162 if (( ${# toks[@]} != 0 )) ; then
1144- # 2>/dev/null for direct invocation, e.g. in the _comp_compgen_filedir
1145- # unit test
1146- compopt -o filenames 2> /dev/null
1163+ # compopt 2>/dev/null for direct invocation, e.g. in
1164+ # _comp_compgen_filedir unit test
1165+ if [[ $_filenames ]]; then
1166+ local i
1167+ for i in " ${! toks[@]} " ; do
1168+ if [[ -d ${toks[i]} ]]; then
1169+ toks[i]+=/
1170+ compopt -o nospace 2> /dev/null
1171+ fi
1172+ done
1173+ else
1174+ compopt -o filenames 2> /dev/null
1175+ fi
11471176 fi
11481177
11491178 # Note: bash < 4.4 has a bug that all the elements are connected with
0 commit comments