@@ -1273,9 +1273,15 @@ _comp_quote_compgen()
12731273
12741274# This function performs file and directory completion. It's better than
12751275# simply using 'compgen -f', because it honours spaces in filenames.
1276- # @param $1 If `-d', complete only on directories. Otherwise filter/pick only
1277- # completions with `.$1' and the uppercase version of it as file
1278- # extension.
1276+ # @param $1 Complete filenames matching `.$1' and the uppercase version of it.
1277+ # Ignored with `-d`.
1278+ # OPTIONS
1279+ # -d Complete only on directories
1280+ # -f Perform `compopt -o filenames` modifications manually. This
1281+ # suffixes a slash to a directory name. This can be combined with
1282+ # the `-C dir` option to `_comp_compgen`, where the generated
1283+ # filenames do not exist in the current working directory and Bash
1284+ # fails to properly detect the filenames.
12791285# @return 0 if at least one completion is generated, or 1 otherwise.
12801286#
12811287# @since 2.12
@@ -1284,9 +1290,22 @@ _comp_compgen_filedir()
12841290 _comp_compgen_tilde && return
12851291
12861292 local -a toks
1293+ local _dir=" " _filenames=" "
1294+ local OPTIND=1 OPTARG=" " OPTERR=0 _opt
1295+ while getopts " :df" _opt " $@ " ; do
1296+ case $_opt in
1297+ d) _dir=set ;;
1298+ f) _filenames=set ;;
1299+ * )
1300+ printf " bash_completion: %s: usage error\n" " $FUNCNAME " >&2
1301+ return 2
1302+ ;;
1303+ esac
1304+ done
1305+ shift " $(( OPTIND - 1 )) "
12871306 local _arg=${1-}
12881307
1289- if [[ $_arg == -d ]]; then
1308+ if [[ $_dir ]]; then
12901309 _comp_compgen -v toks -- -d
12911310 else
12921311 local REPLY
@@ -1330,9 +1349,19 @@ _comp_compgen_filedir()
13301349 fi
13311350
13321351 if (( ${# toks[@]} != 0 )) ; then
1333- # 2>/dev/null for direct invocation, e.g. in the _comp_compgen_filedir
1334- # unit test
1335- compopt -o filenames 2> /dev/null
1352+ # compopt 2>/dev/null for direct invocation, e.g. in
1353+ # _comp_compgen_filedir unit test
1354+ if [[ $_filenames ]]; then
1355+ local i
1356+ for i in " ${! toks[@]} " ; do
1357+ if [[ -d ${toks[i]} ]]; then
1358+ toks[i]+=/
1359+ compopt -o nospace 2> /dev/null
1360+ fi
1361+ done
1362+ else
1363+ compopt -o filenames 2> /dev/null
1364+ fi
13361365 fi
13371366
13381367 # Note: bash < 4.4 has a bug that all the elements are connected with
0 commit comments