1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-11 13:01:28 +02:00

24585: completion for glob qualifiers plus

bug fix for _alternative
This commit is contained in:
Peter Stephenson 2008-02-23 00:10:24 +00:00
parent 2130732433
commit 485a008075
8 changed files with 393 additions and 3 deletions

View file

@ -1,3 +1,14 @@
2008-02-23 Peter Stephenson <p.w.stephenson@ntlworld.com>
* 24585: Completion/Base/Utility/_alternative,
Completion/Unix/Type/_path_files,
Completion/Zsh/Type/_delimiters,
Completion/Zsh/Type/_globqual_delims,
Completion/Zsh/Type/_globquals,
Completion/Zsh/Type/_history_modifiers, Doc/Zsh/compsys.yo:
completion for glob qualifiers plus bug fix for message-only
completion in _alternative.
2008-02-22 Peter Stephenson <pws@csr.com> 2008-02-22 Peter Stephenson <pws@csr.com>
* unposted: Completion/Unix/Command/_perforce: new option * unposted: Completion/Unix/Command/_perforce: new option

View file

@ -75,7 +75,7 @@ while _tags; do
done done
for descr in "$mesgs[@]"; do for descr in "$mesgs[@]"; do
_message -e "${descr%%:*}" "${desc#*:}" _message -e "${descr%%:*}" "${descr#*:}"
done done
return 1 return 1

View file

@ -6,8 +6,9 @@
local linepath realpath donepath prepath testpath exppath skips skipped local linepath realpath donepath prepath testpath exppath skips skipped
local tmp1 tmp2 tmp3 tmp4 i orig eorig pre suf tpre tsuf opre osuf cpre local tmp1 tmp2 tmp3 tmp4 i orig eorig pre suf tpre tsuf opre osuf cpre
local pats haspats ignore pfx pfxsfx sopt gopt opt sdirs ignpar cfopt listsfx local pats haspats ignore pfx pfxsfx sopt gopt opt sdirs ignpar cfopt listsfx
local nm=$compstate[nmatches] menu matcher mopts sort match mid accex fake local nm=$compstate[nmatches] menu matcher mopts sort mid accex fake
local listfiles listopts tmpdisp local listfiles listopts tmpdisp
local -a match mbegin mend
typeset -U prepaths exppaths typeset -U prepaths exppaths
@ -349,7 +350,19 @@ for prepath in "$prepaths[@]"; do
tmp2=( "$tmp1[@]" ) tmp2=( "$tmp1[@]" )
if [[ "$tpre$tsuf" = */* ]]; then # Look for glob qualifiers.
# Extra nastiness to be careful about a quoted parenthesis.
# The initial tests look for parentheses with zero or an
# even number of backslashes in front.
# The later test looks for an outstanding quote.
if [[ ( -o bareglobqual && \
"$tpre/$tsuf" = (#b)((*[^\\]|)(\\\\)#\()([^\)]#) || \
-o extendedglob && \
"$tpre/$tsuf" = (#b)((*[^\\]|)(\\\\)#"(#q")([^\)]#) \
) && -z $compstate[quote] ]]; then
compset -p ${#match[1]}
_globquals
elif [[ "$tpre$tsuf" = */* ]]; then
compfiles -P$cfopt tmp1 accex "$skipped" "$_matcher $matcher[2]" "$sdirs" fake compfiles -P$cfopt tmp1 accex "$skipped" "$_matcher $matcher[2]" "$sdirs" fake
elif [[ "$sopt" = *[/f]* ]]; then elif [[ "$sopt" = *[/f]* ]]; then
compfiles -p$cfopt tmp1 accex "$skipped" "$_matcher $matcher[2]" "$sdirs" fake "$pats[@]" compfiles -p$cfopt tmp1 accex "$skipped" "$_matcher $matcher[2]" "$sdirs" fake "$pats[@]"

View file

@ -0,0 +1,16 @@
#autoload
# Simple function to offer delimiters for modifiers and qualifers.
# Single argument is tag to use.
local expl
local -a list
zstyle -a ":completion:${curcontext}:$1" delimiters list ||
list=(: + / - %)
if (( ${#list} )); then
_wanted delimiters expl delimiter compadd -S '' -a list
else
_message delimiter
fi

View file

@ -0,0 +1,24 @@
#autoload
# Helper for _globquals. Sets delim to delimiter to match.
# don't restore special parameters
compstate[restore]=no
delim=$PREFIX[1]
compset -p 1
# One of matching brackets?
# These don't actually work: the parser gets very confused.
local matchl="<({[" matchr=">)}]"
integer ind=${matchl[(I)$delim]}
(( ind )) && delim=$matchr[ind]
if compset -P "[^$delim]#$delim"; then
# Completely matched.
return 0
else
# Still in delimiter
return 1
fi

View file

@ -0,0 +1,233 @@
#autoload
local state=qual expl char delim
local -a alts
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 "mode spec"
return
fi
fi
;;
(e)
# complete/skip delimited command line
if [[ -z $PREFIX ]]; then
_delimiters qualifer-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 [[ -z $PREFIX ]]; then
_message device ID
return
fi
# It's pointless trying to complete the device.
# Simply assume it's done.
compset -p '[[:digit:]]##'
;;
(l)
# complete/skip link count
if [[ PREFIX = ([-+]|) ]]; then
_message link count
return
fi
# It's pointless trying to complete the link count.
# Simply assume it's done.
compset -P '([-+]|)[[:digit:]]##'
;;
(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
_delimiter qualifier-g
return
elif ! _globqual_delims; then
# still completing group
_groups -S $delim
return
fi
fi
;;
([amc])
if ! compset -P '([Mwhms]|)([-+]|)<->'; then
# complete/skip relative time spec
alts=()
if ! compset -P '[Mwhms]' && [[ -z $PREFIX ]]; then
alts+=(
"time-specifiers:time specifier:\
((M\:months w\:weeks h\:hours m:\minutes s\:seconds))")
fi
if ! compset -P '[-+]' && [[ -z $PREFIX ]]; then
alts+=("senses:sense:((-\:less\ than +\:more\ than))")
fi
alts+=('digits:digit: ')
_alternative $alts
return
fi
;;
(L)
# complete/skip file size
if ! compset -P '([kKmMpP]|)([-+]|)<->'; then
# complete/skip size spec
alts=()
if ! compset -P '[kKmMpP]' && [[ -z $PREFIX ]]; then
alts+=(
"size-specifiers:size specifier:\
((k\:kb m\:mb 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"
)
_describe -t sort-specifiers "sort specifier" alts -Q -S ''
return
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
return
;;
esac
done
case $state in
(qual)
local -a quals
quals=(
"/:directories"
"F:non-empty directories"
".:plain files"
"@:symbolic links"
"=:sockets"
"p:name 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"
"[:+ range of files"
"):end of qualifiers"
"\::modifier"
)
_describe -t globquals "glob qualifier" quals -Q -S ''
;;
esac

View file

@ -0,0 +1,84 @@
#autoload
# Complete history-style modifiers; the first : will have
# been matched and compset -p 1'd.
# The single argument is the type of context:
# h history
# q glob qualifier
# p parameter
local -a list
local type=$1 delim expl
integer global
while true; do
if [[ -n $PREFIX ]]; then
local char=$PREFIX[1]
global=0
compset -p 1
case $char in
([hretpqQxlu\&])
# single character modifiers
;;
(s)
# match delimiter string delimiter string delimiter
if [[ -z $PREFIX ]]; then
_delimiters modifier-s
return
fi
delim=$PREFIX[1]
compset -p 1
if ! compset "[^$delim]#$delim[^$delim]#$delim"; then
if compset "[^$delim]#$delim"; then
_message original string
else
_message replacement string
fi
return
fi
;;
(g)
global=1
continue
;;
esac
# modifier completely matched, see what's next.
compset -P : && continue
# if there's something other than colon next, bummer
[[ -n $PREFIX ]] && return 1
list=("\::modifier")
[[ $type = g ]] && list+=("):end of qualifiers")
# strictly we want a normal suffix if end of qualifiers
_describe -t delimiters "delimiter" list -Q -S ''
else
list=(
"s:substitute string"
"&:repeat substitution"
)
if (( ! global )); then
list+=(
"g:globally apply s or &"
"h:head - strip trailing path element"
"t:tail - strip directories"
"r:root - strip suffix"
"e:leave only extension"
"Q:strip quotes"
"l:lower case all words"
"u:upper case all words"
)
[[ $type = h ]] && list+=(
"p:print without executing"
"x:quote words, breaking on whitespace"
)
[[ $type = [hp] ]] && list+=("q:quote to escape further substitutions")
fi
_describe -t modifiers "modifier" list -Q -S ''
return
fi
done

View file

@ -1262,6 +1262,15 @@ This style is used by the tt(_list) completer function to decide if
insertion of matches should be delayed unconditionally. The default is insertion of matches should be delayed unconditionally. The default is
`true'. `true'.
) )
kindex(delimiters, completion style)
item(tt(delimiters))(
This style is used when adding a delimiter for use with history
modifiers or glob qualifiers that have delimited arguments. It is
an array of preferred delimiters to add. Non-special characters are
preferred as the completion system may otherwise become confused.
The default list is tt(:), tt(+), tt(/), tt(-), tt(%). The list
may be empty to force a delimiter to be typed.
)
kindex(disabled, completion style) kindex(disabled, completion style)
item(tt(disabled))( item(tt(disabled))(
If this is set to `true', the tt(_expand_alias) completer and bindable If this is set to `true', the tt(_expand_alias) completer and bindable