mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-05-19 14:36:04 +02:00
263 lines
5.9 KiB
Plaintext
263 lines
5.9 KiB
Plaintext
#autoload
|
|
|
|
local state=qual expl char delim timespec
|
|
local -a alts tdisp sdisp
|
|
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 )
|
|
alts+=( "time-specifiers:time specifier:compadd -E 0 -d tdisp -S '' - s m h d w M" )
|
|
fi
|
|
if ! compset -P '[-+]' && [[ -z $PREFIX ]]; then
|
|
sdisp=( before exactly since )
|
|
alts+=("senses:sense:compadd -E 0 -d sdisp -S '' - + '' -")
|
|
fi
|
|
specmap=( M months w weeks h hours m minutes s seconds '(|+|-|d)' days)
|
|
alts+=('digits:digit ('${${specmap[(K)$timespec]}:-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 "?"; 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
|