Skip to content

Commit f823c9c

Browse files
committed
feat(_comp_compgen): support option -C
1 parent 036c34d commit f823c9c

File tree

9 files changed

+75
-58
lines changed

9 files changed

+75
-58
lines changed

bash_completion

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,23 @@ _comp_split()
381381
((_new_size > _old_size))
382382
}
383383

384+
# Helper function for _comp_compgen
385+
# @var[in] $?
386+
# @var[in] _var
387+
# @var[in] _append
388+
# @return original $?
389+
_comp_compgen__error_fallback()
390+
{
391+
local _status=$?
392+
if [[ $_append ]]; then
393+
# make sure existence of variable
394+
eval -- "$_var+=()"
395+
else
396+
eval -- "$_var=()"
397+
fi
398+
return "$_status"
399+
}
400+
384401
# Provide a common interface to generate completion candidates in COMPREPLY or
385402
# in a specified array.
386403
# OPTIONS
@@ -398,6 +415,7 @@ _comp_split()
398415
# -c cur Set a word used as a prefix to filter the completions. The default
399416
# is ${cur-}.
400417
# -R The same as -c ''. Use raw outputs without filtering.
418+
# -C dir Evaluate compgen/generator in the specified directory.
401419
# @var[in,opt] cur Used as the default value of a prefix to filter the
402420
# completions.
403421
#
@@ -421,10 +439,10 @@ _comp_split()
421439
# as `-v arr` as a part of the `_comp_compgen` options.
422440
#
423441
# Usage #2: _comp_compgen [-alR|-v arr|-c cur] name args...
424-
# Call `_comp_compgen_NAME ARGS...` with the specified options. This provides
425-
# a common interface to call the functions `_comp_compgen_NAME`, which produce
426-
# completion candidates, with custom options [-alR|-v arr|-c cur]. The option
427-
# `-F sep` is not used with this usage.
442+
# Call the generator `_comp_compgen_NAME ARGS...` with the specified options.
443+
# This provides a common interface to call the functions `_comp_compgen_NAME`,
444+
# which produce completion candidates, with custom options [-alR|-v arr|-c
445+
# cur]. The option `-F sep` is not used with this usage.
428446
# @param $1... name args Calls the function _comp_compgen_NAME with the
429447
# specified ARGS (if $1 does not start with a hyphen `-`). The options
430448
# [-alR|-v arr|-c cur] are inherited by the child calls of `_comp_compgen`
@@ -467,10 +485,15 @@ _comp_compgen()
467485
local _append=${_comp_compgen__append-}
468486
local _var=${_comp_compgen__var-COMPREPLY}
469487
local _cur=${_comp_compgen__cur-${cur-}}
470-
local _ifs=$' \t\n'
488+
local _ifs=$' \t\n' _dir=""
471489

490+
local _old_nocasematch=""
491+
if shopt -q nocasematch; then
492+
_old_nocasematch=set
493+
shopt -u nocasematch
494+
fi
472495
local OPTIND=1 OPTARG="" OPTERR=0 _opt
473-
while getopts ':alF:v:Rc:' _opt "$@"; do
496+
while getopts ':alF:v:Rc:C:' _opt "$@"; do
474497
case $_opt in
475498
a) _append=set ;;
476499
v)
@@ -484,6 +507,13 @@ _comp_compgen()
484507
F) _ifs=$OPTARG ;;
485508
c) _cur=$OPTARG ;;
486509
R) _cur="" ;;
510+
C)
511+
if [[ ! $OPTARG || ! -d $OPTARG ]]; then
512+
printf 'bash_completion: %s: -C: invalid directory name `%s'\''.\n' "$FUNCNAME" "$OPTARG" >&2
513+
return 2
514+
fi
515+
_dir=$OPTARG
516+
;;
487517
*)
488518
printf 'bash_completion: %s: usage error\n' "$FUNCNAME" >&2
489519
return 2
@@ -494,8 +524,10 @@ _comp_compgen()
494524
if (($# == 0)); then
495525
printf 'bash_completion: %s: unexpected number of arguments.\n' "$FUNCNAME" >&2
496526
printf 'usage: %s [-alR|-F SEP|-v ARR|-c CUR] -- ARGS...' "$FUNCNAME" >&2
527+
[[ $_old_nocasematch ]] && shopt -s nocasematch
497528
return 2
498529
fi
530+
[[ $_old_nocasematch ]] && shopt -s nocasematch
499531

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

539+
if [[ $_dir ]]; then
540+
local _original_pwd=$PWD
541+
local PWD=$PWD OLDPWD=$OLDPWD
542+
command cd -- "$_dir" &>/dev/null ||
543+
{
544+
_comp_compgen__error_fallback
545+
return
546+
}
547+
fi
548+
507549
local _comp_compgen__append=$_append
508550
local _comp_compgen__var=$_var
509551
local _comp_compgen__cur=$_cur cur=$_cur
510552
# Note: we use $1 as a part of a function name, and we use $2... as
511553
# arguments to the function if any.
512554
# shellcheck disable=SC2145
513555
_comp_compgen_"$@"
514-
return
556+
local _status=$?
557+
558+
# shellcheck disable=SC2164
559+
[[ $dir ]] && command cd -- "$_original_pwd"
560+
561+
return "$_status"
515562
fi
516563

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

534581
local _result
535582
_result=$(
583+
if [[ $_dir ]]; then
584+
# Note: We also redirect stdout because `cd` may output the target
585+
# directory to stdout when CDPATH is set.
586+
command cd -- "$_dir" &>/dev/null || return
587+
fi
536588
IFS=$_ifs compgen "$@" ${_cur:+-- "$_cur"}
537589
) || {
538-
local _status=$?
539-
if [[ $_append ]]; then
540-
# make sure existence of variable
541-
eval -- "$_var+=()"
542-
else
543-
eval -- "$_var=()"
544-
fi
545-
return "$_status"
590+
_comp_compgen__error_fallback
591+
return
546592
}
547593

548594
_comp_split -l ${_append:+-a} "$_var" "$_result"

completions/_mount.linux

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,11 @@ _comp_cmd_mount()
3737
return
3838
;;
3939
-L)
40-
COMPREPLY=($(
41-
command cd "/dev/disk/by-label/" 2>/dev/null || return
42-
compgen -f -- "$cur"
43-
))
40+
_comp_compgen -C "/dev/disk/by-label/" -- -f
4441
return
4542
;;
4643
-U)
47-
COMPREPLY=($(
48-
command cd "/dev/disk/by-uuid/" 2>/dev/null || return
49-
compgen -f -- "$cur"
50-
))
44+
_comp_compgen -C "/dev/disk/by-uuid/" -- -f
5145
return
5246
;;
5347
-O | --test-opts)

completions/_slackpkg

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,22 +65,16 @@ _comp_cmd_slackpkg()
6565
;;
6666
install-template | remove-template)
6767
if [[ -e $confdir/templates ]]; then
68-
COMPREPLY=($(
69-
command cd -- "$confdir/templates"
70-
compgen -f -X "!*.template" -- "$cur"
71-
))
72-
COMPREPLY=(${COMPREPLY[@]%.template})
68+
_comp_compgen -C "$confdir/templates" -- -f -X \
69+
"!?*.template" && COMPREPLY=("${COMPREPLY[@]%.template}")
7370
fi
7471
return
7572
;;
7673
remove)
7774
_comp_compgen_filedir
7875
COMPREPLY+=($(compgen -W 'a ap d e f k kde kdei l n t tcl x
7976
xap xfce y' -- "$cur"))
80-
COMPREPLY+=($(
81-
command cd /var/log/packages
82-
compgen -f -- "$cur"
83-
))
77+
_comp_compgen -aC /var/log/packages -- -f
8478
return
8579
;;
8680
install | reinstall | upgrade | blacklist | download)

completions/_umount.linux

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,8 @@ _comp_cmd_umount__linux_fstab()
8181
local i
8282
for i in ${!COMPREPLY[*]}; do
8383
[[ ${COMPREPLY[i]} == "$realcur"* ]] &&
84-
COMPREPLY+=($(command cd -- "$dircur" 2>/dev/null &&
85-
compgen -f -d -P "$dircur" \
86-
-X "!${COMPREPLY[i]##"$dirrealcur"}" -- "$basecur"))
84+
_comp_compgen -aC "$dircur" -c "$basecur" -- \
85+
-f -d -P "$dircur" -X "!${COMPREPLY[i]##"$dirrealcur"}"
8786
done
8887
fi
8988
fi

completions/feh

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,12 @@ _comp_cmd_feh()
2929
fi
3030
local font_path
3131
# font_path="$(imlib2-config --prefix 2>/dev/null)/share/imlib2/data/fonts"
32-
# COMPREPLY=( $(command cd -- "$font_path" 2>/dev/null; compgen -f \
33-
# -X "!*.@([tT][tT][fF])" -S / -- "$cur") )
32+
# _comp_compgen -C "$font_path" -- -f -X "!*.@([tT][tT][fF])" -S /
3433
for ((i = ${#words[@]} - 1; i > 0; i--)); do
3534
if [[ ${words[i]} == -@(C|-fontpath) ]]; then
3635
font_path="${words[i + 1]}"
37-
COMPREPLY+=($(
38-
command cd -- "$font_path" 2>/dev/null
39-
compgen -f \
40-
-X "!*.@([tT][tT][fF])" -S / -- "$cur"
41-
))
36+
_comp_compgen -aC "$font_path" -- \
37+
-f -X "!*.@([tT][tT][fF])" -S /
4238
fi
4339
done
4440
compopt -o nospace

completions/removepkg

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@ _comp_cmd_removepkg()
1515
fi
1616

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

completions/sbopkg

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,8 @@ _comp_cmd_sbopkg()
6464
COMPREPLY=($(
6565
command sed -ne "/^SLACKBUILD NAME: $cur/{s/^SLACKBUILD NAME: //;p}" \
6666
"$REPO_ROOT/$REPO_NAME/$REPO_BRANCH/SLACKBUILDS.TXT"
67-
)
68-
$(
69-
command cd -- "$QUEUEDIR"
70-
compgen -f -X "!*.sqf" -- "$cur"
7167
))
68+
_comp_compgen -aC "$QUEUEDIR" -- -f -X "!*.sqf"
7269
} &&
7370
complete -F _comp_cmd_sbopkg sbopkg
7471

completions/slapt-get

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,7 @@ _comp_cmd_slapt_get()
6969
return
7070
;;
7171
ins) # --remove|--filelist
72-
COMPREPLY=($(
73-
command cd /var/log/packages
74-
compgen -f -- "$cur"
75-
))
72+
_comp_compgen -C /var/log/packages -- -f
7673
return
7774
;;
7875
set) # --install-set

completions/xdg-mime

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ _comp_cmd_xdg_mime__mimetype()
55
local d i
66
local -a arr
77
for d in /usr/share/mime /usr/local/share/mime; do
8-
arr=($(
9-
command cd "$d" 2>/dev/null || exit 1
10-
compgen -f -o plusdirs -X "!*.xml" -- "$cur"
11-
)) || continue
8+
_comp_compgen -v arr -C "$d" -- -f -o plusdirs -X "!*.xml" || continue
129
for i in "${!arr[@]}"; do
1310
case ${arr[i]} in
1411
packages*) unset -v "arr[i]" ;; # not a MIME type dir

0 commit comments

Comments
 (0)