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