Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 14 additions & 18 deletions bash_completion
Original file line number Diff line number Diff line change
Expand Up @@ -1289,11 +1289,14 @@ _comp_quote_compgen()
# Ignored with `-d`.
# OPTIONS
# -d Complete only on directories

# -f Perform `compopt -o filenames` modifications manually. This
# suffixes a slash to a directory name. When "-C <dir>" or "-P
# <prefix>" is specified to the "_comp_compgen" call, this option
# is automatically turned on.
# -X PATTERN
# @since 2.18 Specify the filename pattern to exclude, or the
# filename pattern to include prefixed by "!". When this option is
# specified, $1 should be empty or not specified.
# @return 0 if at least one completion is generated, or 1 otherwise.
#
# @since 2.12
Expand All @@ -1302,7 +1305,7 @@ _comp_compgen_filedir()
_comp_compgen_tilde && return

local -a toks
local _dir="" _filenames=""
local _dir="" _filenames="" _xspec=""
if [[ ${_comp_compgen__dir-} || ${_comp_compgen__prefix-} ]]; then
# When "-C <dir>" or "-P <prefix>" is specified, the working directory
# does not contain the generated candidates as filenames. In the case
Expand All @@ -1317,10 +1320,11 @@ _comp_compgen_filedir()
fi

local OPTIND=1 OPTARG="" OPTERR=0 _opt
while getopts ":df" _opt "$@"; do
while getopts ":dfX:" _opt "$@"; do
case $_opt in
d) _dir=set ;;
f) _filenames=set ;;
X) _xspec=$OPTARG ;;
*)
printf "bash_completion: %s: usage error\n" "$FUNCNAME" >&2
return 2
Expand All @@ -1329,6 +1333,10 @@ _comp_compgen_filedir()
done
shift "$((OPTIND - 1))"
local _arg=${1-}
if [[ $_xspec && $_arg ]]; then
printf 'bash_completion: %s: "-X xspec" and "$1" cannot be specified simultaneously\n' "$FUNCNAME" >&2
return 2
fi

if [[ $_dir ]]; then
_comp_compgen -v toks -- -d
Expand All @@ -1344,7 +1352,7 @@ _comp_compgen_filedir()
# Munge xspec to contain uppercase version too
# https://lists.gnu.org/archive/html/bug-bash/2010-09/msg00036.html
# news://news.gmane.io/4C940E1C.1010304@case.edu
local _xspec=${_arg:+"!*.@($_arg|${_arg^^})"}
[[ $_xspec ]] || _xspec=${_arg:+"!*.@($_arg|${_arg^^})"}

local _opts=(-f -X "$_xspec")
# Use plusdirs to get dir completions if we have a xspec; if we don't,
Expand Down Expand Up @@ -1543,20 +1551,8 @@ _comp_variable_assignments()

case $prev in
TZ)
cur=/usr/share/zoneinfo/$cur
_comp_compgen_filedir
if ((${#COMPREPLY[@]})); then
for i in "${!COMPREPLY[@]}"; do
if [[ ${COMPREPLY[i]} == *.tab ]]; then
unset -v 'COMPREPLY[i]'
continue
elif [[ -d ${COMPREPLY[i]} ]]; then
COMPREPLY[i]+=/
compopt -o nospace
fi
COMPREPLY[i]=${COMPREPLY[i]#/usr/share/zoneinfo/}
done
fi
_comp_compgen -C /usr/share/zoneinfo filedir -f \
-X '@(*.tab|leapseconds|leap-seconds.list|tzdata.zi)'
;;
TERM)
_comp_compgen_terms
Expand Down
6 changes: 1 addition & 5 deletions completions-core/lvm.bash
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@ _comp_cmd_lvm__logicalvolumes()
_comp_compgen_split -- "$(lvscan 2>/dev/null |
command sed -n -e "s|^.*'\(.*\)'.*$|\1|p")"
if [[ $cur == /dev/mapper/* ]]; then
_comp_compgen -a filedir
local i
for i in "${!COMPREPLY[@]}"; do
[[ ${COMPREPLY[i]} == */control ]] && unset -v 'COMPREPLY[i]'
done
_comp_compgen -a filedir -X '*/control'
fi
}

Expand Down
3 changes: 1 addition & 2 deletions completions-core/ssh.bash
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,7 @@ _comp_xfunc_ssh_compgen_identityfile()
{
local cur=$cur tmp
[[ ! $cur && -d ~/.ssh ]] && cur=~/.ssh/id
_comp_compgen -v tmp -c "$cur" filedir &&
_comp_compgen -U tmp -- -W '"${tmp[@]}"' -X "${1:+!}*.pub"
_comp_compgen -c "$cur" filedir -X "${1:+!}*.pub"
}

_comp_deprecate_func 2.12 _ssh_identityfile _comp_xfunc_ssh_compgen_identityfile
Expand Down
9 changes: 9 additions & 0 deletions test/t/unit/test_unit_compgen_filedir.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ def functions(self, request, bash):
"_fcd() { local cur=$(_get_cword); unset -v COMPREPLY; _comp_compgen -C _filedir filedir -d; };"
"complete -F _fcd fcd",
)
assert_bash_exec(
bash,
"_X() { local cur;_comp_get_words cur; unset -v COMPREPLY; _comp_compgen_filedir -X '*.e1'; }; "
"complete -F _X X",
)

@pytest.fixture(scope="class")
def non_windows_testdir(self, bash, tmp_path_factory):
Expand Down Expand Up @@ -312,6 +317,10 @@ def test_29_dotdot(self, bash, functions, funcname):
"..folder/",
]

def test_option_X_1(self, bash, functions):
completion = assert_complete(bash, "X ", cwd="_filedir/ext")
assert completion == sorted("ff.e2 foo/ hh.e2 ii.E1".split())

def test_fallback_1(self, bash, functions):
"""Directory names should also be generated by the filedir fallback"""
with bash_env_saved(bash) as bash_env:
Expand Down