Skip to content

Commit

Permalink
feat(_comp_compgen): support option -C
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed May 9, 2023
1 parent ddce016 commit 670eb47
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 58 deletions.
76 changes: 61 additions & 15 deletions bash_completion
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,23 @@ _comp_split()
((_new_size > _old_size))
}

# Helper function for _comp_compgen
# @var[in] $?
# @var[in] _var
# @var[in] _append
# @return original $?
_comp_compgen__error_fallback()
{
local _status=$?
if [[ $_append ]]; then
# make sure existence of variable
eval -- "$_var+=()"
else
eval -- "$_var=()"
fi
return "$_status"
}

# Provide a common interface to generate completion candidates in COMPREPLY or
# in a specified array.
# OPTIONS
Expand All @@ -398,6 +415,7 @@ _comp_split()
# -c cur Set a word used as a prefix to filter the completions. The default
# is ${cur-}.
# -R The same as -c ''. Use raw outputs without filtering.
# -C dir Evaluate compgen/generator in the specified directory.
# @var[in,opt] cur Used as the default value of a prefix to filter the
# completions.
#
Expand All @@ -421,10 +439,10 @@ _comp_split()
# as `-v arr` as a part of the `_comp_compgen` options.
#
# Usage #2: _comp_compgen [-alR|-v arr|-c cur] name args...
# Call `_comp_compgen_NAME ARGS...` with the specified options. This provides
# a common interface to call the functions `_comp_compgen_NAME`, which produce
# completion candidates, with custom options [-alR|-v arr|-c cur]. The option
# `-F sep` is not used with this usage.
# Call the generator `_comp_compgen_NAME ARGS...` with the specified options.
# This provides a common interface to call the functions `_comp_compgen_NAME`,
# which produce completion candidates, with custom options [-alR|-v arr|-c
# cur]. The option `-F sep` is not used with this usage.
# @param $1... name args Calls the function _comp_compgen_NAME with the
# specified ARGS (if $1 does not start with a hyphen `-`). The options
# [-alR|-v arr|-c cur] are inherited by the child calls of `_comp_compgen`
Expand Down Expand Up @@ -467,10 +485,15 @@ _comp_compgen()
local _append=${_comp_compgen__append-}
local _var=${_comp_compgen__var-COMPREPLY}
local _cur=${_comp_compgen__cur-${cur-}}
local _ifs=$' \t\n'
local _ifs=$' \t\n' _dir=""

local _old_nocasematch=""
if shopt -q nocasematch; then
_old_nocasematch=set
shopt -u nocasematch
fi
local OPTIND=1 OPTARG="" OPTERR=0 _opt
while getopts ':alF:v:Rc:' _opt "$@"; do
while getopts ':alF:v:Rc:C:' _opt "$@"; do
case $_opt in
a) _append=set ;;
v)
Expand All @@ -484,6 +507,13 @@ _comp_compgen()
F) _ifs=$OPTARG ;;
c) _cur=$OPTARG ;;
R) _cur="" ;;
C)
if [[ ! $OPTARG || ! -d $OPTARG ]]; then
printf 'bash_completion: %s: -C: invalid directory name `%s'\''.\n' "$FUNCNAME" "$OPTARG" >&2
return 2
fi
_dir=$OPTARG
;;
*)
printf 'bash_completion: %s: usage error\n' "$FUNCNAME" >&2
return 2
Expand All @@ -494,8 +524,10 @@ _comp_compgen()
if (($# == 0)); then
printf 'bash_completion: %s: unexpected number of arguments.\n' "$FUNCNAME" >&2
printf 'usage: %s [-alR|-F SEP|-v ARR|-c CUR] -- ARGS...' "$FUNCNAME" >&2
[[ $_old_nocasematch ]] && shopt -s nocasematch
return 2
fi
[[ $_old_nocasematch ]] && shopt -s nocasematch

if [[ $1 != -* ]]; then
# usage: _comp_compgen [options] NAME args
Expand All @@ -504,14 +536,29 @@ _comp_compgen()
return 2
fi

if [[ $_dir ]]; then
local _original_pwd=$PWD
local PWD=$PWD OLDPWD=$OLDPWD
command cd -- "$_dir" &>/dev/null ||
{
_comp_compgen__error_fallback
return
}
fi

local _comp_compgen__append=$_append
local _comp_compgen__var=$_var
local _comp_compgen__cur=$_cur cur=$_cur
# Note: we use $1 as a part of a function name, and we use $2... as
# arguments to the function if any.
# shellcheck disable=SC2145
_comp_compgen_"$@"
return
local _status=$?

# shellcheck disable=SC2164
[[ $_dir ]] && command cd -- "$_original_pwd"

return "$_status"
fi

# usage: _comp_compgen [options] -- [compgen_options]
Expand All @@ -533,16 +580,15 @@ _comp_compgen()

local _result
_result=$(
if [[ $_dir ]]; then
# Note: We also redirect stdout because `cd` may output the target
# directory to stdout when CDPATH is set.
command cd -- "$_dir" &>/dev/null || return
fi
IFS=$_ifs compgen "$@" ${_cur:+-- "$_cur"}
) || {
local _status=$?
if [[ $_append ]]; then
# make sure existence of variable
eval -- "$_var+=()"
else
eval -- "$_var=()"
fi
return "$_status"
_comp_compgen__error_fallback
return
}

_comp_split -l ${_append:+-a} "$_var" "$_result"
Expand Down
10 changes: 2 additions & 8 deletions completions/_mount.linux
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,11 @@ _comp_cmd_mount()
return
;;
-L)
COMPREPLY=($(
command cd "/dev/disk/by-label/" 2>/dev/null || return
compgen -f -- "$cur"
))
_comp_compgen -C "/dev/disk/by-label/" -- -f
return
;;
-U)
COMPREPLY=($(
command cd "/dev/disk/by-uuid/" 2>/dev/null || return
compgen -f -- "$cur"
))
_comp_compgen -C "/dev/disk/by-uuid/" -- -f
return
;;
-O | --test-opts)
Expand Down
12 changes: 3 additions & 9 deletions completions/_slackpkg
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,16 @@ _comp_cmd_slackpkg()
;;
install-template | remove-template)
if [[ -e $confdir/templates ]]; then
COMPREPLY=($(
command cd -- "$confdir/templates"
compgen -f -X "!*.template" -- "$cur"
))
COMPREPLY=(${COMPREPLY[@]%.template})
_comp_compgen -C "$confdir/templates" -- -f -X \
"!?*.template" && COMPREPLY=("${COMPREPLY[@]%.template}")
fi
return
;;
remove)
_comp_compgen_filedir
COMPREPLY+=($(compgen -W 'a ap d e f k kde kdei l n t tcl x
xap xfce y' -- "$cur"))
COMPREPLY+=($(
command cd /var/log/packages
compgen -f -- "$cur"
))
_comp_compgen -aC /var/log/packages -- -f
return
;;
install | reinstall | upgrade | blacklist | download)
Expand Down
5 changes: 2 additions & 3 deletions completions/_umount.linux
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,8 @@ _comp_cmd_umount__linux_fstab()
local i
for i in ${!COMPREPLY[*]}; do
[[ ${COMPREPLY[i]} == "$realcur"* ]] &&
COMPREPLY+=($(command cd -- "$dircur" 2>/dev/null &&
compgen -f -d -P "$dircur" \
-X "!${COMPREPLY[i]##"$dirrealcur"}" -- "$basecur"))
_comp_compgen -aC "$dircur" -c "$basecur" -- \
-f -d -P "$dircur" -X "!${COMPREPLY[i]##"$dirrealcur"}"
done
fi
fi
Expand Down
10 changes: 3 additions & 7 deletions completions/feh
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,12 @@ _comp_cmd_feh()
fi
local font_path
# font_path="$(imlib2-config --prefix 2>/dev/null)/share/imlib2/data/fonts"
# COMPREPLY=( $(command cd -- "$font_path" 2>/dev/null; compgen -f \
# -X "!*.@([tT][tT][fF])" -S / -- "$cur") )
# _comp_compgen -C "$font_path" -- -f -X "!*.@([tT][tT][fF])" -S /
for ((i = ${#words[@]} - 1; i > 0; i--)); do
if [[ ${words[i]} == -@(C|-fontpath) ]]; then
font_path="${words[i + 1]}"
COMPREPLY+=($(
command cd -- "$font_path" 2>/dev/null
compgen -f \
-X "!*.@([tT][tT][fF])" -S / -- "$cur"
))
_comp_compgen -aC "$font_path" -- \
-f -X "!*.@([tT][tT][fF])" -S /
fi
done
compopt -o nospace
Expand Down
5 changes: 1 addition & 4 deletions completions/removepkg
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ _comp_cmd_removepkg()
fi

local root=${ROOT:-/}
COMPREPLY=($(
command cd -- "$root/var/log/packages" 2>/dev/null || return 1
compgen -f -- "$cur"
))
_comp_compgen -C "$root/var/log/packages" -- -f
} &&
complete -F _comp_cmd_removepkg removepkg

Expand Down
5 changes: 1 addition & 4 deletions completions/sbopkg
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,8 @@ _comp_cmd_sbopkg()
COMPREPLY=($(
command sed -ne "/^SLACKBUILD NAME: $cur/{s/^SLACKBUILD NAME: //;p}" \
"$REPO_ROOT/$REPO_NAME/$REPO_BRANCH/SLACKBUILDS.TXT"
)
$(
command cd -- "$QUEUEDIR"
compgen -f -X "!*.sqf" -- "$cur"
))
_comp_compgen -aC "$QUEUEDIR" -- -f -X "!*.sqf"
} &&
complete -F _comp_cmd_sbopkg sbopkg

Expand Down
5 changes: 1 addition & 4 deletions completions/slapt-get
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,7 @@ _comp_cmd_slapt_get()
return
;;
ins) # --remove|--filelist
COMPREPLY=($(
command cd /var/log/packages
compgen -f -- "$cur"
))
_comp_compgen -C /var/log/packages -- -f
return
;;
set) # --install-set
Expand Down
5 changes: 1 addition & 4 deletions completions/xdg-mime
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ _comp_cmd_xdg_mime__mimetype()
local d i
local -a arr
for d in /usr/share/mime /usr/local/share/mime; do
arr=($(
command cd "$d" 2>/dev/null || exit 1
compgen -f -o plusdirs -X "!*.xml" -- "$cur"
)) || continue
_comp_compgen -v arr -C "$d" -- -f -o plusdirs -X "!*.xml" || continue
for i in "${!arr[@]}"; do
case ${arr[i]} in
packages*) unset -v "arr[i]" ;; # not a MIME type dir
Expand Down

0 comments on commit 670eb47

Please sign in to comment.