Skip to content

Commit a7fa31b

Browse files
authored
Merge pull request #973 from akinomyoga/_comp_compgen-4
fix: use `_comp_compgen` with API changes
2 parents a17197f + 6b3dfa5 commit a7fa31b

25 files changed

+221
-113
lines changed

bash_completion

Lines changed: 76 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,23 @@ _comp_split()
397397
((_new_size > _old_size))
398398
}
399399

400+
# Helper function for _comp_compgen
401+
# @var[in] $?
402+
# @var[in] _var
403+
# @var[in] _append
404+
# @return original $?
405+
_comp_compgen__error_fallback()
406+
{
407+
local _status=$?
408+
if [[ $_append ]]; then
409+
# make sure existence of variable
410+
eval -- "$_var+=()"
411+
else
412+
eval -- "$_var=()"
413+
fi
414+
return "$_status"
415+
}
416+
400417
# Provide a common interface to generate completion candidates in COMPREPLY or
401418
# in a specified array.
402419
# OPTIONS
@@ -414,6 +431,7 @@ _comp_split()
414431
# -c cur Set a word used as a prefix to filter the completions. The default
415432
# is ${cur-}.
416433
# -R The same as -c ''. Use raw outputs without filtering.
434+
# -C dir Evaluate compgen/generator in the specified directory.
417435
# @var[in,opt] cur Used as the default value of a prefix to filter the
418436
# completions.
419437
#
@@ -437,10 +455,10 @@ _comp_split()
437455
# as `-v arr` as a part of the `_comp_compgen` options.
438456
#
439457
# Usage #2: _comp_compgen [-alR|-v arr|-c cur] name args...
440-
# Call `_comp_compgen_NAME ARGS...` with the specified options. This provides
441-
# a common interface to call the functions `_comp_compgen_NAME`, which produce
442-
# completion candidates, with custom options [-alR|-v arr|-c cur]. The option
443-
# `-F sep` is not used with this usage.
458+
# Call the generator `_comp_compgen_NAME ARGS...` with the specified options.
459+
# This provides a common interface to call the functions `_comp_compgen_NAME`,
460+
# which produce completion candidates, with custom options [-alR|-v arr|-c
461+
# cur]. The option `-F sep` is not used with this usage.
444462
# @param $1... name args Calls the function _comp_compgen_NAME with the
445463
# specified ARGS (if $1 does not start with a hyphen `-`). The options
446464
# [-alR|-v arr|-c cur] are inherited by the child calls of `_comp_compgen`
@@ -484,10 +502,15 @@ _comp_compgen()
484502
local _append=${_comp_compgen__append-}
485503
local _var=${_comp_compgen__var-COMPREPLY}
486504
local _cur=${_comp_compgen__cur-${cur-}}
487-
local _ifs=$' \t\n'
505+
local _ifs=$' \t\n' _dir=""
488506

507+
local _old_nocasematch=""
508+
if shopt -q nocasematch; then
509+
_old_nocasematch=set
510+
shopt -u nocasematch
511+
fi
489512
local OPTIND=1 OPTARG="" OPTERR=0 _opt
490-
while getopts ':alF:v:Rc:' _opt "$@"; do
513+
while getopts ':alF:v:Rc:C:' _opt "$@"; do
491514
case $_opt in
492515
a) _append=set ;;
493516
v)
@@ -501,12 +524,20 @@ _comp_compgen()
501524
F) _ifs=$OPTARG ;;
502525
c) _cur=$OPTARG ;;
503526
R) _cur="" ;;
527+
C)
528+
if [[ ! $OPTARG ]]; then
529+
printf 'bash_completion: %s: -C: invalid directory name `%s'\''.\n' "$FUNCNAME" "$OPTARG" >&2
530+
return 2
531+
fi
532+
_dir=$OPTARG
533+
;;
504534
*)
505535
printf 'bash_completion: %s: usage error\n' "$FUNCNAME" >&2
506536
return 2
507537
;;
508538
esac
509539
done
540+
[[ $_old_nocasematch ]] && shopt -s nocasematch
510541
shift "$((OPTIND - 1))"
511542
if (($# == 0)); then
512543
printf 'bash_completion: %s: unexpected number of arguments.\n' "$FUNCNAME" >&2
@@ -521,14 +552,35 @@ _comp_compgen()
521552
return 2
522553
fi
523554

555+
if [[ $_dir ]]; then
556+
local _original_pwd=$PWD
557+
local PWD=${PWD-} OLDPWD=${OLDPWD-}
558+
# Note: We also redirect stdout because `cd` may output the target
559+
# directory to stdout when CDPATH is set.
560+
command cd -- "$_dir" &>/dev/null ||
561+
{
562+
_comp_compgen__error_fallback
563+
return
564+
}
565+
fi
566+
524567
local _comp_compgen__append=$_append
525568
local _comp_compgen__var=$_var
526569
local _comp_compgen__cur=$_cur cur=$_cur
527570
# Note: we use $1 as a part of a function name, and we use $2... as
528571
# arguments to the function if any.
529572
# shellcheck disable=SC2145
530573
_comp_compgen_"$@"
531-
return
574+
local _status=$?
575+
576+
# Go back to the original directory.
577+
# Note: Failure of this line results in the change of the current
578+
# directory visible to the user. We intentionally do not redirect
579+
# stderr so that the error message appear in the terminal.
580+
# shellcheck disable=SC2164
581+
[[ $_dir ]] && command cd -- "$_original_pwd"
582+
583+
return "$_status"
532584
fi
533585

534586
# usage: _comp_compgen [options] -- [compgen_options]
@@ -550,16 +602,15 @@ _comp_compgen()
550602

551603
local _result
552604
_result=$(
605+
if [[ $_dir ]]; then
606+
# Note: We also redirect stdout because `cd` may output the target
607+
# directory to stdout when CDPATH is set.
608+
command cd -- "$_dir" &>/dev/null || return
609+
fi
553610
IFS=$_ifs compgen "$@" ${_cur:+-- "$_cur"}
554611
) || {
555-
local _status=$?
556-
if [[ $_append ]]; then
557-
# make sure existence of variable
558-
eval -- "$_var+=()"
559-
else
560-
eval -- "$_var=()"
561-
fi
562-
return "$_status"
612+
_comp_compgen__error_fallback
613+
return
563614
}
564615

565616
_comp_split -l ${_append:+-a} "$_var" "$_result"
@@ -1508,13 +1559,19 @@ _available_interfaces()
15081559
}
15091560

15101561
# Echo number of CPUs, falling back to 1 on failure.
1511-
# TODO:API: rename per conventions, rework to use vars rather than outputting
1512-
_ncpus()
1562+
# @var[out] ret
1563+
# @return 0 if it successfully obtained the number of CPUs, or otherwise 1
1564+
# @since 2.12
1565+
_comp_get_ncpus()
15131566
{
15141567
local var=NPROCESSORS_ONLN
15151568
[[ $OSTYPE == *@(linux|msys|cygwin)* ]] && var=_$var
1516-
local n=$(getconf $var 2>/dev/null)
1517-
printf %s "${n:-1}"
1569+
if ret=$(getconf $var 2>/dev/null) && ((ret >= 1)); then
1570+
return 0
1571+
else
1572+
ret=1
1573+
return 1
1574+
fi
15181575
}
15191576

15201577
# Perform tilde (~) completion

bash_completion.d/000_bash_completion_compat.bash

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,4 +335,12 @@ _parse_usage()
335335
return 0
336336
}
337337

338+
# @deprecated 2.12 Use `_comp_get_ncpus`.
339+
_ncpus()
340+
{
341+
local ret
342+
_comp_get_ncpus
343+
printf %s "$ret"
344+
}
345+
338346
# ex: filetype=sh

completions/2to3

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ _comp_cmd_2to3()
1515
return
1616
;;
1717
-j | --processes)
18-
COMPREPLY=($(compgen -W "{1..$(_ncpus)}" -- "$cur"))
18+
local ret
19+
_comp_get_ncpus
20+
_comp_compgen -- -W "{1..$ret}"
1921
return
2022
;;
2123
-o | --output-dir)

completions/_modules

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,26 @@
2121
# being sourced before it and thus before the `module' alias has been defined.
2222
[[ -f /etc/profile.d/modules.sh ]] || return 1
2323

24-
# TODO:API: rename per conventions, rework to use vars rather than outputting
25-
_module_list()
24+
_comp_cmd_module__compgen_list()
2625
{
2726
local modules="$(command sed 's/:/ /g' <<<"$LOADEDMODULES" | sort)"
28-
compgen -W "$modules" -- "$1"
27+
_comp_compgen -- -W "$modules"
2928
}
3029

31-
# TODO:API: rename per conventions, rework to use vars rather than outputting
32-
_module_path()
30+
_comp_cmd_module__compgen_path()
3331
{
3432
local modules="$(command sed 's/:/ /g' <<<"$MODULEPATH" | sort)"
35-
compgen -W "$modules" -- "$1"
33+
_comp_compgen -- -W "$modules"
3634
}
3735

38-
# TODO:API: rename per conventions, rework to use vars rather than outputting
39-
_module_avail()
36+
_comp_cmd_module__compgen_avail()
4037
{
4138
local modules="$(
4239
module avail 2>&1 |
4340
command grep -E -v '^(-|$)' |
4441
xargs printf '%s\n' | command sed -e 's/(default)//g' | sort
4542
)"
46-
47-
compgen -W "$modules" -- "$1"
43+
_comp_compgen -- -W "$modules"
4844
}
4945

5046
# A completion function for the module alias
@@ -65,19 +61,23 @@ _comp_cmd_module()
6561
elif ((cword == 2)); then
6662
case $prev in
6763
add | display | help | load | show | whatis)
68-
COMPREPLY=($(_module_avail "$cur"))
64+
# TODO:API: use generator call?
65+
_comp_cmd_module__compgen_avail
6966
;;
7067
rm | switch | swap | unload | update)
71-
COMPREPLY=($(_module_list "$cur"))
68+
# TODO:API: use generator call?
69+
_comp_cmd_module__compgen_list
7270
;;
7371
unuse)
74-
COMPREPLY=($(_module_path "$cur"))
72+
# TODO:API: use generator call?
73+
_comp_cmd_module__compgen_path
7574
;;
7675
esac
7776
elif ((cword == 3)); then
7877
case ${words[1]} in
7978
swap | switch)
80-
COMPREPLY=($(_module_avail "$cur"))
79+
# TODO:API: use generator call?
80+
_comp_cmd_module__compgen_avail
8181
;;
8282
esac
8383
fi

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
_comp_compgen -a -- -W 'a ap d e f k kde kdei l n t tcl x xap xfce
7976
y'
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

0 commit comments

Comments
 (0)