#autoload local state=qual expl char delim timespec default MATCH integer MBEGIN MEND local -a alts tdisp sdisp tmatch smatch local -A specmap while [[ -n $PREFIX ]]; do char=$PREFIX[1] compset -p 1 case $char in ([-/F.@=p*rwxAIERWXsStUG^MTNDn,]) # no argument ;; (%) # optional b, c if [[ $PREFIX[1] = [bc] ]]; then compset -p 1 fi ;; (f) if ! compset -P "[-=+][0-7?]##"; then if [[ -z $PREFIX ]]; then _delimiters qualifier-f return elif ! _globqual_delims; then # still completing mode spec _message -e modes "mode spec" return fi fi ;; (P) # skip delimited prefix if [[ -z $PREFIX ]]; then _delimiters qualifier-P return elif ! _globqual_delims; then # can't suggest anything here _message -e prefix prefix return fi ;; (e) # complete/skip delimited command line if [[ -z $PREFIX ]]; then _delimiters qualifier-e return elif ! _globqual_delims; then # still completing command to eval compset -q _normal return fi ;; (+) # complete/skip command name (no delimiters) if [[ $PREFIX = [[:IDENT:]]# ]]; then # either nothing there yet, or still on name _command_names return fi compset -P '[[:IDENT:]]##' ;; (d) # complete/skip device if ! compset -p '[[:digit:]]##'; then _message -e device-ids "device ID" return fi ;; (l) # complete/skip link count if ! compset -P '([-+]|)[[:digit:]]##'; then _message -e numbers "link count" return fi ;; (u) # complete/skip UID or delimited user if ! compset -P '[[:digit:]]##'; then if [[ -z $PREFIX ]]; then _delimiters qualifier-u return elif ! _globqual_delims; then # still completing user _users -S $delim return fi fi ;; (g) # complete/skip GID or delimited group if ! compset -P '[[:digit:]]##'; then if [[ -z $PREFIX ]]; then _delimiters qualifier-g return elif ! _globqual_delims; then # still completing group _groups -S $delim return fi fi ;; ([amc]) if ! compset -P '([Mwhmsd]|)([-+]|)<->'; then # complete/skip relative time spec alts=() timespec=$PREFIX[1] if ! compset -P '[Mwhmsd]' && [[ -z $PREFIX ]]; then tdisp=( seconds minutes hours days weeks Months ) tmatch=( s m h d w M ) if zstyle -t ":completion:${curcontext}:time-specifiers" verbose; then zstyle -s ":completion:${curcontext}:time-specifiers" list-separator sep || sep=-- print -v tdisp -f "%s ${sep//(#m)[%\\]/$MATCH$MATCH} %s" ${tmatch:^^tdisp} fi alts+=( "time-specifiers:time specifier:compadd -E 0 -d tdisp -S '' -a tmatch" ) fi if ! compset -P '[-+]' && [[ -z $PREFIX ]]; then sdisp=( before exactly since ) smatch=( - '' + ) if zstyle -t ":completion:${curcontext}:senses" verbose; then zstyle -s ":completion:${curcontext}:senses" list-separator sep || sep=-- default=" [default exactly]" sdisp=( "- $sep before" "+ $sep since" ) smatch=( - + ) else sdisp=( before exactly since ) smatch=( - '' + ) fi alts+=( "senses:sense${default}:compadd -E 0 -d sdisp -S '' -a smatch" ) fi specmap=( M months w weeks h hours m minutes s seconds '(|+|-|d)' days) alts+=('digits:digit ('${${specmap[(K)${timespec:-d}]}:-invalid time specifier}'):_dates -f ${${timespec/[-+]/d}:-d} -S ""' ) _alternative $alts return fi ;; (L) # complete/skip file size if ! compset -P '([kKmMgGtTpP]|)([-+]|)<->'; then # complete/skip size spec alts=() if ! compset -P '[kKmMgGtTpP]' && [[ -z $PREFIX ]]; then alts+=( "size-specifiers:size specifier:\ ((k\:kb m\:mb g\:gb t\:tb p\:512-byte\ blocks))") fi if ! compset -P '[-+]' && [[ -z $PREFIX ]]; then alts+=("senses:sense:((-\:less\ than +\:more\ than))") fi alts+=('digits:digit: ') _alternative $alts return fi ;; ([oO]) # complete/skip sort spec if ! compset -p 1; then alts=( "n:lexical order of name" "L:size of file" "l:number of hard links" "a:last access time" "m:last modification time" "c:last inode change time" "d:directory depth" "N:no sorting" "e:execute code" "+:+ command name" ) _describe -t sort-specifiers "sort specifier" alts -Q -S '' return elif [[ $IPREFIX[-1] = e ]]; then if [[ -z $PREFIX ]]; then _delimiters qualifier-oe return elif ! _globqual_delims; then compset -q _normal return fi elif [[ $IPREFIX[-1] = + ]]; then if [[ $PREFIX = [[:IDENT:]]# ]]; then # either nothing there yet, or still on name _command_names return fi fi ;; (\[) # complete/skip range: check for closing bracket if ! compset -P "(-|)[[:digit:]]##(,(-|)[[:digit:]]##|)]"; then if compset -P "(-|)[[:digit:]]##,"; then _message "end of range" else _message "start of range" fi return fi ;; (:) # complete modifiers and don't stop completing them _history_modifiers q return ;; esac done case $state in (qual) local -a quals quals=( "/:directories" "F:non-empty directories" ".:plain files" "@:symbolic links" "=:sockets" "p:named pipes (FIFOs)" "*:executable plain files" "%:device files" "r:owner-readable" "w:owner-writeable" "x:owner-executable" "A:group-readable" "I:group-writeable" "E:group-executable" "R:world-readable" "W:world-writeable" "X:world-executable" "s:setuid" "S:setgid" "t:sticky bit set" "f:+ access rights" "e:execute code" "+:+ command name" "d:+ device" "l:+ link count" "U:owned by EUID" "G:owned by EGID" "u:+ owning user" "g:+ owning group" "a:+ access time" "m:+ modification time" "c:+ inode change time" "L:+ size" "^:negate qualifiers" "-:follow symlinks toggle" "M:mark directories" "T:mark types" "N:use NULL_GLOB" "D:glob dots" "n:numeric glob sort" "o:+ sort order, up" "O:+ sort order, down" "P:prepend word" "Y:+ at most ARG matches" "[:+ range of files" "):end of qualifiers" "\::modifier" ) _describe -t globquals "glob qualifier" quals -Q -S '' ;; esac