@@ -224,25 +224,97 @@ _comp_compact()
224
224
_comp_compact__array=(" ${_comp_compact__array[@]} " )
225
225
}
226
226
227
+ # @version bash-4.3
228
+ _comp_xfunc_ARRAY_reverse ()
229
+ {
230
+ _comp_compact " $1 "
231
+ local -n _comp_reverse__arr=$1
232
+ local _comp_reverse__i=0
233
+ local _comp_reverse__j=$(( ${# _comp_reverse__arr[@]} - 1 ))
234
+ local _comp_reverse__tmp
235
+ while (( _comp_reverse__i < _comp_reverse__j)) ; do
236
+ _comp_reverse__tmp=${_comp_reverse__arr[_comp_reverse__i]}
237
+ _comp_reverse__arr[_comp_reverse__i]=${_comp_reverse__arr[_comp_reverse__j]}
238
+ _comp_reverse__arr[_comp_reverse__j]=$_comp_reverse__tmp
239
+ (( _comp_reverse__i++, _comp_reverse__j-- ))
240
+ done
241
+ }
242
+
243
+ # usage: _comp_index_of [-EFGpxmxrl] array pattern
227
244
# Find the index of a matching element
245
+ # Options:
246
+ #
247
+ # -EFGe Select the type of the pattern. The default is -F.
248
+ # -psmx Select the anchoring option.
249
+ # -r Revert the condition.
250
+ # See _comp_xfunc_ARRAY_filter for the details of these options.
251
+ #
252
+ # -l Get the last index of matching elements.
253
+ #
228
254
# @var[out] ret
229
255
# @version bash-4.3
230
256
_comp_index_of ()
231
257
{
232
- # TODO getopts -> -r gets rightmost (last) index
233
- # TODO getopts: -R uses regex instead of glob
234
- local -n _comp_index_of__array=$1
235
- local _comp_compact__pattern=$2
236
-
237
- local -i _comp_index_of__i
238
- for _comp_index_of__i in " ${! _comp_index_of__array[@]} " ; do
239
- # shellcheck disable=SC2053
240
- if [[ ${_comp_index_of__array[_comp_index_of__i]} == $_comp_compact__pattern ]]; then
241
- ret=$_comp_index_of__i
242
- return 0
243
- fi
258
+ local _old_nocasematch=" "
259
+ if shopt -q nocasematch; then
260
+ _old_nocasematch=set
261
+ shopt -u nocasematch
262
+ fi
263
+ local _flags=" " _pattype=F _anchoring=" "
264
+ local OPTIND=1 OPTARG=" " OPTERR=0 _opt=" "
265
+ while getopts ' EFGepsmxrl' _opt " $@ " ; do
266
+ case $_opt in
267
+ [EFGe]) _pattype=$_opt ;;
268
+ [psmx]) _anchoring=$_opt ;;
269
+ [rl]) _flags+=$_opt ;;
270
+ * )
271
+ printf ' bash_completion: %s: %s\n' " $FUNCNAME " ' usage error' >&2
272
+ printf ' usage: %s %s\n' " $FUNCNAME " " [-EFGepsmxrl] ARRAY_NAME CONDITION" >&2
273
+ return 2
274
+ ;;
275
+ esac
244
276
done
277
+ shift " $(( OPTIND - 1 )) "
278
+ if (( $# != 2 )) ; then
279
+ printf ' bash_completion: %s: %s\n' " $FUNCNAME " " unexpected number of arguments: $# " >&2
280
+ printf ' usage: %s %s\n' " $FUNCNAME " " [-EFGepsmxrl] ARRAY_NAME CONDITION" >&2
281
+ [[ $_old_nocasematch ]] && shopt -s nocasematch
282
+ return 2
283
+ elif [[ $1 != [a-zA-Z_]* ([a-zA-Z_0-9]) ]]; then
284
+ printf ' bash_completion: %s: %s\n' " $FUNCNAME " " invalid array name '$1 '." >&2
285
+ [[ $_old_nocasematch ]] && shopt -s nocasematch
286
+ return 2
287
+ elif [[ $1 == @ (_* | OPTIND| OPTARG| OPTERR) ]]; then
288
+ printf ' bash_completion: %s: %s\n' " $FUNCNAME " " array name '$1 ' is reserved for internal uses" >&2
289
+ [[ $_old_nocasematch ]] && shopt -s nocasematch
290
+ return 2
291
+ fi
292
+ [[ $_old_nocasematch ]] && shopt -s nocasematch
245
293
246
294
ret=-1
295
+
296
+ local -n _array=$1
297
+ if (( ${# _array[@]} )) ; then
298
+ local _predicate
299
+ _comp_xfunc_ARRAY__init_predicate " $2 " " $_pattype " " $_anchoring " " $_flags "
300
+
301
+ local -a _indices=(" ${! _array[@]} " )
302
+ [[ $_flags == * l* ]] && _comp_xfunc_ARRAY_reverse _indices
303
+
304
+ local -i _i
305
+ for _i in " ${_indices[@]} " ; do
306
+ _comp_xfunc_ARRAY__predicate " ${_array[_i]} "
307
+ case $? in
308
+ 0)
309
+ ret=$_i
310
+ return 0
311
+ ;;
312
+ 1) continue ;;
313
+ 27) return 27 ;;
314
+ * ) return 2 ;;
315
+ esac
316
+ done
317
+ fi
318
+
247
319
return 1
248
320
}
0 commit comments