@@ -1095,9 +1095,15 @@ _comp_quote_compgen()
10951095
10961096# This function performs file and directory completion. It's better than
10971097# simply using 'compgen -f', because it honours spaces in filenames.
1098- # @param $1 If `-d', complete only on directories. Otherwise filter/pick only
1099- # completions with `.$1' and the uppercase version of it as file
1100- # extension.
1098+ # @param $1 Complete filenames matching `.$1' and the uppercase version of it.
1099+ # Ignored with `-d`.
1100+ # OPTIONS
1101+ # -d Complete only on directories
1102+ # -f Perform `compopt -f filenames` modifications manually. This
1103+ # suffixes a slash to a directory name. This can be combined with
1104+ # the `-C dir` option to `_comp_compgen`, where the generated
1105+ # filenames do not exist in the current working directory and Bash
1106+ # fails to properly detect the filenames.
11011107# @return 0 if at least one completion is generated, or 1 otherwise.
11021108#
11031109# @since 2.12
@@ -1106,9 +1112,22 @@ _comp_compgen_filedir()
11061112 _comp_compgen_tilde && return
11071113
11081114 local -a toks
1115+ local _dir=" " _filenames=" "
1116+ local OPTIND=1 OPTARG=" " OPTERR=0 _opt
1117+ while getopts " :df" _opt " $@ " ; do
1118+ case $_opt in
1119+ d) _dir=set ;;
1120+ f) _filenames=set ;;
1121+ * )
1122+ printf " bash_completion: %s: usage error\n" " $FUNCNAME " >&2
1123+ return 2
1124+ ;;
1125+ esac
1126+ done
1127+ shift " $(( OPTIND - 1 )) "
11091128 local _arg=${1-}
11101129
1111- if [[ $_arg == -d ]]; then
1130+ if [[ $_dir ]]; then
11121131 _comp_compgen -v toks -- -d
11131132 else
11141133 local REPLY
@@ -1143,9 +1162,19 @@ _comp_compgen_filedir()
11431162 fi
11441163
11451164 if (( ${# toks[@]} != 0 )) ; then
1146- # 2>/dev/null for direct invocation, e.g. in the _comp_compgen_filedir
1147- # unit test
1148- compopt -o filenames 2> /dev/null
1165+ # compopt 2>/dev/null for direct invocation, e.g. in
1166+ # _comp_compgen_filedir unit test
1167+ if [[ $_filenames ]]; then
1168+ local i
1169+ for i in " ${! toks[@]} " ; do
1170+ if [[ -d ${toks[i]} ]]; then
1171+ toks[i]+=/
1172+ compopt -o nospace 2> /dev/null
1173+ fi
1174+ done
1175+ else
1176+ compopt -o filenames 2> /dev/null
1177+ fi
11491178 fi
11501179
11511180 # Note: bash < 4.4 has a bug that all the elements are connected with
0 commit comments