Skip to content

Commit 11c28cf

Browse files
committed
refactor(xfunc ARRAY filter): separate predicate
1 parent 19ca11b commit 11c28cf

File tree

1 file changed

+92
-49
lines changed

1 file changed

+92
-49
lines changed

completions/ARRAY

Lines changed: 92 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,87 @@
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+
#
11+
# @var[out] _predicate[0] command
12+
# @var[out] _predicate[1] pattern
13+
# @var[out] _predicate[2] type
14+
# @var[out] _predicate[3] revert
15+
_comp_xfunc_ARRAY__init_predicate()
16+
{
17+
_predicate[0]=false
18+
_predicate[1]=$1
19+
_predicate[2]=$2
20+
_predicate[3]=""
21+
22+
local old_nocasematch=""
23+
if shopt -q nocasematch; then
24+
old_nocasematch=set
25+
shopt -u nocasematch
26+
fi
27+
28+
local _pattype=$2 _anchoring=${3-} flags=${4-}
29+
case $_pattype in
30+
E)
31+
case $_anchoring in
32+
p) _predicate[0]='[[ $_value =~ ^(${_predicate[1]}) ]]' ;;
33+
s) _predicate[0]='[[ $_value =~ (${_predicate[1]})$ ]]' ;;
34+
x) _predicate[0]='[[ $_value =~ ^(${_predicate[1]})$ ]]' ;;
35+
*) _predicate[0]='[[ $_value =~ ${_predicate[1]} ]]' ;;
36+
esac
37+
;;
38+
F)
39+
case $_anchoring in
40+
p) _predicate[0]='[[ $_value == "${_predicate[1]}"* ]]' ;;
41+
s) _predicate[0]='[[ $_value == *"${_predicate[1]}" ]]' ;;
42+
x) _predicate[0]='[[ $_value == "${_predicate[1]}" ]]' ;;
43+
*) _predicate[0]='[[ $_value == *"${_predicate[1]}"* ]]' ;;
44+
esac
45+
;;
46+
G)
47+
case $_anchoring in
48+
p) _predicate[0]='[[ $_value == ${_predicate[1]}* ]]' ;;
49+
s) _predicate[0]='[[ $_value == *${_predicate[1]} ]]' ;;
50+
m) _predicate[0]='[[ $_value == *${_predicate[1]}* ]]' ;;
51+
*) _predicate[0]='[[ $_value == ${_predicate[1]} ]]' ;;
52+
esac
53+
;;
54+
*)
55+
if type -t "$2" &>/dev/null; then
56+
_predicate[0]="$2 \"\$_value\""
57+
else
58+
_predicate[0]="local -x value=\$_value; $2"
59+
fi
60+
;;
61+
esac
62+
63+
[[ $_flags == *r* ]] && _predicate[3]=set
64+
[[ $old_nocasematch ]] && shopt -s nocasematch
65+
}
66+
67+
_comp_xfunc_ARRAY__predicate()
68+
{
69+
local _value=$1
70+
eval "${_predicate[0]}"
71+
72+
local _ext=$?
73+
case $_ext in
74+
[01]) [[ ${_predicate[3]} ]] && _ext=$((1 - _ext)) ;;
75+
27) ;;
76+
*)
77+
printf 'bash_completion: %s: %s\n' "$FUNCNAME" \
78+
"filter condition broken '${_predicate[2]:+-${_predicate[2]} }$2'" >&2
79+
return 2
80+
;;
81+
esac
82+
return "$_ext"
83+
}
84+
385
# Filter the array elements with the specified condition.
486
# @param $1 Array name (that is not "value", "_*" or other internal variable
587
# names)
@@ -80,67 +162,28 @@ _comp_xfunc_ARRAY_filter()
80162
elif [[ $1 == @(_*|OPTIND|OPTARG|OPTERR) ]]; then
81163
printf 'bash_completion: %s: %s\n' "$FUNCNAME" "array name '$1' is reserved for internal uses" >&2
82164
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
86165
fi
87166
# When the array is empty:
88167
eval "((\${#$1[@]}))" || return 0
89168

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
169+
local _predicate
170+
_comp_xfunc_ARRAY__init_predicate "$2" "$_pattype" "$_anchoring" "$_flags"
124171

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

128-
local _indices _index _value
174+
local _indices _index _ref
129175
eval "_indices=(\"\${!$1[@]}\")"
130176
for _index in "${_indices[@]}"; do
131-
eval "_value=\${$1[\$_index]}; $_predicate"
177+
_ref="$1[\$_index]"
178+
_comp_xfunc_ARRAY__predicate "${!_ref}"
132179
case $? in
133-
"$_expected_status") continue ;;
134-
[01])
135-
unset -v "$1[\$_index]"
180+
0) continue ;;
181+
1)
182+
unset -v "$_ref"
136183
_unset=set
137184
;;
138185
27) break ;;
139-
*)
140-
printf 'bash_completion: %s: %s\n' "$FUNCNAME" \
141-
"filter condition broken '${_pattype:+-$_pattype }$2'" >&2
142-
return 2
143-
;;
186+
*) return 2 ;;
144187
esac
145188
done
146189

0 commit comments

Comments
 (0)