summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2008-02-23 00:10:24 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2008-02-23 00:10:24 +0000
commit485a008075ce19bfdf19922c803d1637ebb5255e (patch)
treefce4fa1a9d5ca8b236760b8c9b05bb06e7d9a801
parent21307324337a613ef53e437219ddcbc3f3bb53ff (diff)
downloadzsh-485a008075ce19bfdf19922c803d1637ebb5255e.tar.gz
zsh-485a008075ce19bfdf19922c803d1637ebb5255e.zip
24585: completion for glob qualifiers plus
bug fix for _alternative
-rw-r--r--ChangeLog11
-rw-r--r--Completion/Base/Utility/_alternative2
-rw-r--r--Completion/Unix/Type/_path_files17
-rw-r--r--Completion/Zsh/Type/_delimiters16
-rw-r--r--Completion/Zsh/Type/_globqual_delims24
-rw-r--r--Completion/Zsh/Type/_globquals233
-rw-r--r--Completion/Zsh/Type/_history_modifiers84
-rw-r--r--Doc/Zsh/compsys.yo9
8 files changed, 393 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 18b351bee..7ad5991c9 100644
--- a/ChangeLog
+++ b/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
diff --git a/Completion/Base/Utility/_alternative b/Completion/Base/Utility/_alternative
index c7b71d9bc..bfb34a604 100644
--- a/Completion/Base/Utility/_alternative
+++ b/Completion/Base/Utility/_alternative
@@ -75,7 +75,7 @@ while _tags; do
done
for descr in "$mesgs[@]"; do
- _message -e "${descr%%:*}" "${desc#*:}"
+ _message -e "${descr%%:*}" "${descr#*:}"
done
return 1
diff --git a/Completion/Unix/Type/_path_files b/Completion/Unix/Type/_path_files
index 4176005c3..e75e81efd 100644
--- a/Completion/Unix/Type/_path_files
+++ b/Completion/Unix/Type/_path_files
@@ -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[@]"
diff --git a/Completion/Zsh/Type/_delimiters b/Completion/Zsh/Type/_delimiters
new file mode 100644
index 000000000..bb5bba8d0
--- /dev/null
+++ b/Completion/Zsh/Type/_delimiters
@@ -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
diff --git a/Completion/Zsh/Type/_globqual_delims b/Completion/Zsh/Type/_globqual_delims
new file mode 100644
index 000000000..bba4241e8
--- /dev/null
+++ b/Completion/Zsh/Type/_globqual_delims
@@ -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
diff --git a/Completion/Zsh/Type/_globquals b/Completion/Zsh/Type/_globquals
new file mode 100644
index 000000000..0262c8b6f
--- /dev/null
+++ b/Completion/Zsh/Type/_globquals
@@ -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
diff --git a/Completion/Zsh/Type/_history_modifiers b/Completion/Zsh/Type/_history_modifiers
new file mode 100644
index 000000000..085867159
--- /dev/null
+++ b/Completion/Zsh/Type/_history_modifiers
@@ -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
diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo
index 04fc6ecfa..c609991d6 100644
--- a/Doc/Zsh/compsys.yo
+++ b/Doc/Zsh/compsys.yo
@@ -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