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:
parent
2130732433
commit
485a008075
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>
|
||||
|
||||
* unposted: Completion/Unix/Command/_perforce: new option
|
||||
|
@ -75,7 +75,7 @@ while _tags; do
|
||||
done
|
||||
|
||||
for descr in "$mesgs[@]"; do
|
||||
_message -e "${descr%%:*}" "${desc#*:}"
|
||||
_message -e "${descr%%:*}" "${descr#*:}"
|
||||
done
|
||||
|
||||
return 1
|
||||
|
@ -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[@]"
|
||||
|
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
|
||||
`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
|
||||
|
Loading…
Reference in New Issue
Block a user