crontab, find: Replace some ugly string tricks with associative arrays.

This commit is contained in:
Ville Skyttä 2011-04-27 17:19:29 +03:00
parent a098290816
commit ab6c6890ed
2 changed files with 27 additions and 35 deletions

View File

@ -14,35 +14,31 @@ _crontab()
;; ;;
esac esac
local i opts=" -u -l -r -e" # leading space at start is significant... local -A opts=( [-u]= [-l]= [-r]= [-e]= )
[[ $OSTYPE == *linux* ]] && opts+=" -i" [[ $OSTYPE == *linux* ]] && opts[-i]=
[ -e /etc/selinux ] && opts+=" -s" [ -e /etc/selinux ] && opts[-s]=
local i
for (( i=0; i < ${#words[@]}-1; i++ )); do for (( i=0; i < ${#words[@]}-1; i++ )); do
[[ ${words[i]} ]] && unset opts[${words[i]}]
case "${words[i]}" in case "${words[i]}" in
-l) -l)
opts=${opts// -l -r -e/} unset opts[-r] opts[-e] opts[-i] opts[-s]
opts=${opts// -i/}
opts=${opts// -s/}
;; ;;
-e) -e)
opts=${opts// -l -r -e/} unset opts[-l] opts[-r] opts[-i]
opts=${opts// -i/}
;; ;;
-r) -r)
opts=${opts// -l -r -e/} unset opts[-l] opts[-e]
;; ;;
-u) -u)
opts=${opts// -u/} unset opts[-i]
opts=${opts// -i/}
;;
-i|-s)
opts=${opts// ${words[i]}/}
;; ;;
esac esac
done done
if [[ "$cur" == -* ]]; then if [[ "$cur" == -* ]]; then
COMPREPLY=( $( compgen -W '$opts' -- "$cur" ) ) COMPREPLY=( $( compgen -W '${!opts[@]}' -- "$cur" ) )
return 0 return 0
fi fi

View File

@ -91,27 +91,23 @@ _find()
-delete -exec -execdir -fls -fprint -fprint0 -fprintf -ls -ok -okdir \ -delete -exec -execdir -fls -fprint -fprint0 -fprintf -ls -ok -okdir \
-print -print0 -printf -prune -quit' -- "$cur" ) ) -print -print0 -printf -prune -quit' -- "$cur" ) )
if [[ ${#COMPREPLY[@]} -ne 0 ]]; then
# this removes any options from the list of completions that have # this removes any options from the list of completions that have
# already been specified somewhere on the command line, as long as # already been specified somewhere on the command line, as long as
# these options can only be used once (in a word, "options", in # these options can only be used once (in a word, "options", in
# opposition to "tests" and "actions", as in the find(1) manpage). # opposition to "tests" and "actions", as in the find(1) manpage).
local onlyonce local -A onlyonce=( [-daystart]=1 [-depth]=1 [-follow]=1 [-help]=1
onlyonce=' -daystart -depth -follow -help -ignore_readdir_race -maxdepth \ [-ignore_readdir_race]=1 [-maxdepth]=1 [-mindepth]=1 [-mount]=1
-mindepth -mount -noignore_readdir_race -noleaf -nowarn -regextype \ [-noignore_readdir_race]=1 [-noleaf]=1 [-nowarn]=1 [-regextype]=1
-version -warn -xdev ' [-version]=1 [-warn]=1 [-xdev]=1 )
COMPREPLY=( $( \ local j
(while read -d ' ' i; do for i in "${words[@]}"; do
[[ -z "$i" || "${onlyonce/ ${i%% *} / }" == "$onlyonce" ]] && [[ $i && ${onlyonce[$i]} ]] || continue
continue for j in ${!COMPREPLY[@]}; do
# flatten array with spaces on either side, [[ ${COMPREPLY[j]} == $i ]] && unset COMPREPLY[j]
# otherwise we cannot grep on word boundaries of
# first and last word
COMPREPLY=" ${COMPREPLY[@]} "
# remove word from list of completions
COMPREPLY=( ${COMPREPLY/ ${i%% *} / } )
done done
printf '%s ' "${COMPREPLY[@]}") <<<"${words[@]}" done
) ) fi
_filedir _filedir