@@ -1166,9 +1166,15 @@ _comp_quote_compgen()
11661166
11671167# This function performs file and directory completion. It's better than
11681168# simply using 'compgen -f', because it honours spaces in filenames.
1169- # @param $1 If `-d', complete only on directories. Otherwise filter/pick only
1170- # completions with `.$1' and the uppercase version of it as file
1171- # extension.
1169+ # @param $1 Complete filenames matching `.$1' and the uppercase version of it.
1170+ # Ignored with `-d`.
1171+ # OPTIONS
1172+ # -d Complete only on directories
1173+ # -f Perform `compopt -f filenames` modifications manually. This
1174+ # suffixes a slash to a directory name. This can be combined with
1175+ # the `-C dir` option to `_comp_compgen`, where the generated
1176+ # filenames do not exist in the current working directory and Bash
1177+ # fails to properly detect the filenames.
11721178# @return 0 if at least one completion is generated, or 1 otherwise.
11731179#
11741180# @since 2.12
@@ -1177,9 +1183,22 @@ _comp_compgen_filedir()
11771183 _comp_compgen_tilde && return
11781184
11791185 local -a toks
1186+ local _dir=" " _filenames=" "
1187+ local OPTIND=1 OPTARG=" " OPTERR=0 _opt
1188+ while getopts " :df" _opt " $@ " ; do
1189+ case $_opt in
1190+ d) _dir=set ;;
1191+ f) _filenames=set ;;
1192+ * )
1193+ printf " bash_completion: %s: usage error\n" " $FUNCNAME " >&2
1194+ return 2
1195+ ;;
1196+ esac
1197+ done
1198+ shift " $(( OPTIND - 1 )) "
11801199 local _arg=${1-}
11811200
1182- if [[ $_arg == -d ]]; then
1201+ if [[ $_dir ]]; then
11831202 _comp_compgen -v toks -- -d
11841203 else
11851204 local REPLY
@@ -1223,9 +1242,19 @@ _comp_compgen_filedir()
12231242 fi
12241243
12251244 if (( ${# toks[@]} != 0 )) ; then
1226- # 2>/dev/null for direct invocation, e.g. in the _comp_compgen_filedir
1227- # unit test
1228- compopt -o filenames 2> /dev/null
1245+ # compopt 2>/dev/null for direct invocation, e.g. in
1246+ # _comp_compgen_filedir unit test
1247+ if [[ $_filenames ]]; then
1248+ local i
1249+ for i in " ${! toks[@]} " ; do
1250+ if [[ -d ${toks[i]} ]]; then
1251+ toks[i]+=/
1252+ compopt -o nospace 2> /dev/null
1253+ fi
1254+ done
1255+ else
1256+ compopt -o filenames 2> /dev/null
1257+ fi
12291258 fi
12301259
12311260 # Note: bash < 4.4 has a bug that all the elements are connected with
0 commit comments