1
0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-09-25 05:27:12 +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>
* unposted: Completion/Unix/Command/_perforce: new option

View File

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

View File

@ -6,8 +6,9 @@
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 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 -a match mbegin mend
typeset -U prepaths exppaths
@ -349,7 +350,19 @@ for prepath in "$prepaths[@]"; do
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
elif [[ "$sopt" = *[/f]* ]]; then
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
`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)
item(tt(disabled))(
If this is set to `true', the tt(_expand_alias) completer and bindable