Skip to content

Commit a9a7bd3

Browse files
committed
refactor(xfunc ARRAY filter): separate predicate
1 parent 0508968 commit a9a7bd3

File tree

1 file changed

+91
-49
lines changed

1 file changed

+91
-49
lines changed

completions/ARRAY

+91-49
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,86 @@
11
# Utility xfunc functions for array manipulations -*- shell-script -*-
22

3+
# usage: _comp_xfunc_ARRAY__init_predicate pattern pattype [anchoring flags]
4+
# @param $1 pattern Pattern
5+
# @param $2 pattype /[EFG]/ or empty
6+
# @param[opt] $3 anchoring /[psmx]/ or empty
7+
# @param[opt] $4 flags /r/ or empty
8+
# See _comp_xfunc_ARRAY_filter for details of pattern, pattype,
9+
# anchoring, and flags.
10+
# @var[out] _predicate
11+
# @var[out] _predicate_pat
12+
# @var[out] _predicate_type
13+
# @var[out] _predicate_revert
14+
_comp_xfunc_ARRAY__init_predicate()
15+
{
16+
_predicate=false
17+
_predicate_pat=$1
18+
_predicate_type=$2
19+
_predicate_revert=""
20+
21+
local old_nocasematch=""
22+
if shopt -q nocasematch; then
23+
old_nocasematch=set
24+
shopt -u nocasematch
25+
fi
26+
27+
local _pattype=$2 _anchoring=${3-} flags=${4-}
28+
case $_pattype in
29+
E)
30+
case $_anchoring in
31+
p) _predicate='[[ $_value =~ ^($_predicate_pat) ]]' ;;
32+
s) _predicate='[[ $_value =~ ($_predicate_pat)$ ]]' ;;
33+
x) _predicate='[[ $_value =~ ^($_predicate_pat)$ ]]' ;;
34+
*) _predicate='[[ $_value =~ $_predicate_pat ]]' ;;
35+
esac
36+
;;
37+
F)
38+
case $_anchoring in
39+
p) _predicate='[[ $_value == "$_predicate_pat"* ]]' ;;
40+
s) _predicate='[[ $_value == *"$_predicate_pat" ]]' ;;
41+
x) _predicate='[[ $_value == "$_predicate_pat" ]]' ;;
42+
*) _predicate='[[ $_value == *"$_predicate_pat"* ]]' ;;
43+
esac
44+
;;
45+
G)
46+
case $_anchoring in
47+
p) _predicate='[[ $_value == $_predicate_pat* ]]' ;;
48+
s) _predicate='[[ $_value == *$_predicate_pat ]]' ;;
49+
m) _predicate='[[ $_value == *$_predicate_pat* ]]' ;;
50+
*) _predicate='[[ $_value == $_predicate_pat ]]' ;;
51+
esac
52+
;;
53+
*)
54+
if type -t "$2" &>/dev/null; then
55+
_predicate="$2 \"\$_value\""
56+
else
57+
_predicate="local -x value=\$_value; $2"
58+
fi
59+
;;
60+
esac
61+
62+
[[ $_flags == *r* ]] && _predicate_revert=set
63+
[[ $old_nocasematch ]] && shopt -s nocasematch
64+
}
65+
66+
_comp_xfunc_ARRAY__predicate()
67+
{
68+
local _value=$1
69+
eval "$_predicate"
70+
71+
local _ext=$?
72+
case $_ext in
73+
[01]) [[ $_predicate_revert ]] && _ext=$((1 - _ext)) ;;
74+
27) ;;
75+
*)
76+
printf 'bash_completion: %s: %s\n' "$FUNCNAME" \
77+
"filter condition broken '${_predicate_type:+-$_predicate_type }$2'" >&2
78+
return 2
79+
;;
80+
esac
81+
return "$_ext"
82+
}
83+
384
# Filter the array elements with the specified condition.
485
# @param $1 Array name (that is not "value", "_*" or other internal variable
586
# names)
@@ -80,67 +161,28 @@ _comp_xfunc_ARRAY_filter()
80161
elif [[ $1 == @(_*|OPTIND|OPTARG|OPTERR) ]]; then
81162
printf 'bash_completion: %s: %s\n' "$FUNCNAME" "array name '$1' is reserved for internal uses" >&2
82163
return 2
83-
elif [[ ! $_pattype && $1 == value ]]; then
84-
printf 'bash_completion: %s: %s\n' "$FUNCNAME" "array name '$1' cannot be used for the predicate" >&2
85-
return 2
86164
fi
87165
# When the array is empty:
88166
eval "((\${#$1[@]}))" || return 0
89167

90-
local _predicate='' _pattern=$2
91-
case $_pattype in
92-
E)
93-
case $_anchoring in
94-
p) _predicate='[[ $_value =~ ^($_pattern) ]]' ;;
95-
s) _predicate='[[ $_value =~ ($_pattern)$ ]]' ;;
96-
x) _predicate='[[ $_value =~ ^($_pattern)$ ]]' ;;
97-
*) _predicate='[[ $_value =~ $_pattern ]]' ;;
98-
esac
99-
;;
100-
F)
101-
case $_anchoring in
102-
p) _predicate='[[ $_value == "$_pattern"* ]]' ;;
103-
s) _predicate='[[ $_value == *"$_pattern" ]]' ;;
104-
x) _predicate='[[ $_value == "$_pattern" ]]' ;;
105-
*) _predicate='[[ $_value == *"$_pattern"* ]]' ;;
106-
esac
107-
;;
108-
G)
109-
case $_anchoring in
110-
p) _predicate='[[ $_value == $_pattern* ]]' ;;
111-
s) _predicate='[[ $_value == *$_pattern ]]' ;;
112-
m) _predicate='[[ $_value == *$_pattern* ]]' ;;
113-
*) _predicate='[[ $_value == $_pattern ]]' ;;
114-
esac
115-
;;
116-
*)
117-
if type -t "$2" &>/dev/null; then
118-
_predicate="$2 \"\$_value\""
119-
else
120-
_predicate="local -x value=\$_value; $2"
121-
fi
122-
;;
123-
esac
168+
local _predicate _predicate_pat _predicate_type _predicate_revert
169+
_comp_xfunc_ARRAY__init_predicate "$2" "$_pattype" "$_anchoring" "$_flags"
124170

125-
local _unset="" _expected_status=0
126-
[[ $_flags == *r* ]] && _expected_status=1
171+
local _unset=""
127172

128-
local _indices _index _value
173+
local _indices _index _ref
129174
eval "_indices=(\"\${!$1[@]}\")"
130175
for _index in "${_indices[@]}"; do
131-
eval "_value=\${$1[\$_index]}; $_predicate"
176+
_ref="$1[\$_index]"
177+
_comp_xfunc_ARRAY__predicate "${!_ref}"
132178
case $? in
133-
"$_expected_status") continue ;;
134-
[01])
135-
unset -v "$1[\$_index]"
179+
0) continue ;;
180+
1)
181+
unset -v "$_ref"
136182
_unset=set
137183
;;
138184
27) break ;;
139-
*)
140-
printf 'bash_completion: %s: %s\n' "$FUNCNAME" \
141-
"filter condition broken '${_pattype:+-$_pattype }$2'" >&2
142-
return 2
143-
;;
185+
*) return 2 ;;
144186
esac
145187
done
146188

0 commit comments

Comments
 (0)