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:
parent
2130732433
commit
485a008075
8 changed files with 393 additions and 3 deletions
11
ChangeLog
11
ChangeLog
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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[@]"
|
||||||
|
|
16
Completion/Zsh/Type/_delimiters
Normal file
16
Completion/Zsh/Type/_delimiters
Normal 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
|
24
Completion/Zsh/Type/_globqual_delims
Normal file
24
Completion/Zsh/Type/_globqual_delims
Normal 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
|
233
Completion/Zsh/Type/_globquals
Normal file
233
Completion/Zsh/Type/_globquals
Normal 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
|
84
Completion/Zsh/Type/_history_modifiers
Normal file
84
Completion/Zsh/Type/_history_modifiers
Normal 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
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue