Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(_filedir): add -f to manually suffix / to directory names #847

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
40 changes: 34 additions & 6 deletions bash_completion
Original file line number Diff line number Diff line change
Expand Up @@ -1166,9 +1166,15 @@ _comp_quote_compgen()

# This function performs file and directory completion. It's better than
# simply using 'compgen -f', because it honours spaces in filenames.
# @param $1 If `-d', complete only on directories. Otherwise filter/pick only
# completions with `.$1' and the uppercase version of it as file
# extension.
# @param $1 Complete filenames matching `.$1' and the uppercase version of it.
# Ignored with `-d`.
# OPTIONS
# -d Complete only on directories
# -f Perform `compopt -f filenames` modifications manually. This
# suffixes a slash to a directory name. This can be combined with
# the `-C dir` option to `_comp_compgen`, where the generated
# filenames do not exist in the current working directory and Bash
# fails to properly detect the filenames.
# @return 0 if at least one completion is generated, or 1 otherwise.
#
# @since 2.12
Expand All @@ -1177,9 +1183,22 @@ _comp_compgen_filedir()
_comp_compgen_tilde && return

local -a toks
local _dir="" _filenames=""
local OPTIND=1 OPTARG="" OPTERR=0 _opt
while getopts ":df" _opt "$@"; do
case $_opt in
d) _dir=set ;;
f) _filenames=set ;;
*)
printf "bash_completion: %s: usage error\n" "$FUNCNAME" >&2
return 2
;;
esac
done
shift "$((OPTIND - 1))"
local _arg=${1-}

if [[ $_arg == -d ]]; then
if [[ $_dir ]]; then
_comp_compgen -v toks -- -d
else
local REPLY
Expand Down Expand Up @@ -1223,8 +1242,17 @@ _comp_compgen_filedir()
fi

if ((${#toks[@]} != 0)); then
# 2>/dev/null for direct invocation, e.g. in the _comp_compgen_filedir
# unit test
# compopt 2>/dev/null for direct invocation, e.g. in
# _comp_compgen_filedir unit test
if [[ $_filenames ]]; then
local i
for i in "${!toks[@]}"; do
if [[ -d ${toks[i]} ]]; then
toks[i]+=/
compopt -o nospace 2>/dev/null
fi
done
fi
compopt -o filenames 2>/dev/null
fi

Expand Down
4 changes: 2 additions & 2 deletions completions/_mount.linux
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ _comp_cmd_mount()
return
;;
-L)
_comp_compgen -C "/dev/disk/by-label/" -- -f
_comp_compgen -C "/dev/disk/by-label/" filedir -f
return
;;
-U)
_comp_compgen -C "/dev/disk/by-uuid/" -- -f
_comp_compgen -C "/dev/disk/by-uuid/" filedir -f
return
;;
-O | --test-opts)
Expand Down
6 changes: 3 additions & 3 deletions completions/_slackpkg
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,16 @@ _comp_cmd_slackpkg()
;;
install-template | remove-template)
if [[ -e $confdir/templates ]]; then
_comp_compgen -C "$confdir/templates" -- -f -X \
"!?*.template" && COMPREPLY=("${COMPREPLY[@]%.template}")
_comp_compgen -C "$confdir/templates" filedir -f template &&
COMPREPLY=("${COMPREPLY[@]%.template}")
fi
return
;;
remove)
_comp_compgen_filedir
_comp_compgen -a -- -W 'a ap d e f k kde kdei l n t tcl x xap xfce
y'
_comp_compgen -aC /var/log/packages -- -f
_comp_compgen -aC /var/log/packages filedir -f
return
;;
install | reinstall | upgrade | blacklist | download)
Expand Down
2 changes: 1 addition & 1 deletion completions/removepkg
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ _comp_cmd_removepkg()
fi

local root=${ROOT:-/}
_comp_compgen -C "$root/var/log/packages" -- -f
_comp_compgen -C "$root/var/log/packages" filedir -f
} &&
complete -F _comp_cmd_removepkg removepkg

Expand Down
2 changes: 1 addition & 1 deletion completions/sbopkg
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ _comp_cmd_sbopkg()

_comp_compgen_split -l -- "$(command sed -ne "s/^SLACKBUILD NAME: //p" \
"$file")"
_comp_compgen -aC "$QUEUEDIR" -- -f -X "!*.sqf"
_comp_compgen -aC "$QUEUEDIR" filedir -f sqf
} &&
complete -F _comp_cmd_sbopkg sbopkg

Expand Down
2 changes: 1 addition & 1 deletion completions/slapt-get
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ _comp_cmd_slapt_get()
return
;;
ins) # --remove|--filelist
_comp_compgen -C /var/log/packages -- -f
_comp_compgen -C /var/log/packages filedir -f
return
;;
set) # --install-set
Expand Down
20 changes: 20 additions & 0 deletions test/t/unit/test_unit_compgen_filedir.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,22 @@ def functions(self, request, bash):
"_g() { local cur;_comp_get_words cur; unset -v COMPREPLY; _comp_compgen_filedir e1; }; "
"complete -F _g g",
)
assert_bash_exec(
bash,
"_fc() { local cur=$(_get_cword); unset -v COMPREPLY; _comp_compgen -C _filedir filedir; }; "
"complete -F _fc fc; "
"complete -F _fc -o filenames fc2",
)
assert_bash_exec(
bash,
"_fd() { local cur;_comp_get_words cur; unset -v COMPREPLY; _comp_compgen_filedir -d; };"
"complete -F _fd fd",
)
assert_bash_exec(
bash,
"_fcd() { local cur=$(_get_cword); unset -v COMPREPLY; _comp_compgen -C _filedir filedir -df; };"
"complete -F _fcd fcd",
)

@pytest.fixture(scope="class")
def non_windows_testdir(self, request, bash):
Expand Down Expand Up @@ -68,6 +79,11 @@ def test_2(self, bash, functions, funcname):
completion = assert_complete(bash, "%s ab/" % funcname, cwd="_filedir")
assert completion == "e"

@pytest.mark.parametrize("funcname", "fc fc2".split())
def test_2C(self, bash, functions, funcname):
completion = assert_complete(bash, "%s _filedir ab/" % funcname)
assert completion == "e"

@pytest.mark.parametrize("funcname", "f f2".split())
def test_3(self, bash, functions, funcname):
completion = assert_complete(
Expand Down Expand Up @@ -156,6 +172,10 @@ def test_14(self, bash, functions, funcname):
def test_15(self, functions, completion):
assert completion == "b/"

@pytest.mark.complete(r"fcd a\ ")
def test_15d(self, functions, completion):
assert completion == "b/"

@pytest.mark.complete("g ", cwd="_filedir/ext")
def test_16(self, functions, completion):
assert completion == sorted("ee.e1 foo/ gg.e1 ii.E1".split())
Expand Down
Loading