From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28157 invoked from network); 23 Feb 2008 00:06:32 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.4 (2008-01-01) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.4 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 23 Feb 2008 00:06:32 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 70201 invoked from network); 23 Feb 2008 00:06:24 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 23 Feb 2008 00:06:24 -0000 Received: (qmail 20632 invoked by alias); 23 Feb 2008 00:06:18 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 24585 Received: (qmail 20617 invoked from network); 23 Feb 2008 00:06:18 -0000 Received: from bifrost.dotsrc.org (130.225.254.106) by sunsite.dk with SMTP; 23 Feb 2008 00:06:18 -0000 Received: from mtaout02-winn.ispmail.ntl.com (mtaout02-winn.ispmail.ntl.com [81.103.221.48]) by bifrost.dotsrc.org (Postfix) with ESMTP id 0B0198026E0B for ; Sat, 23 Feb 2008 01:06:13 +0100 (CET) Received: from aamtaout02-winn.ispmail.ntl.com ([81.103.221.35]) by mtaout02-winn.ispmail.ntl.com with ESMTP id <20080223000818.OVKG27871.mtaout02-winn.ispmail.ntl.com@aamtaout02-winn.ispmail.ntl.com> for ; Sat, 23 Feb 2008 00:08:18 +0000 Received: from pws-pc.ntlworld.com ([81.107.42.63]) by aamtaout02-winn.ispmail.ntl.com with ESMTP id <20080223000735.QNUY17393.aamtaout02-winn.ispmail.ntl.com@pws-pc.ntlworld.com> for ; Sat, 23 Feb 2008 00:07:35 +0000 Received: from pws-pc (pws-pc [127.0.0.1]) by pws-pc.ntlworld.com (8.14.2/8.14.2) with ESMTP id m1N04RAh011165 for ; Sat, 23 Feb 2008 00:04:27 GMT From: Peter Stephenson To: zsh-workers@sunsite.dk (Zsh hackers list) Subject: PATCH: completion of glob qualifiers X-Mailer: MH-E 8.0.3; nmh 1.2-20070115cvs; GNU Emacs 22.1.1 Date: Sat, 23 Feb 2008 00:04:27 +0000 Message-ID: <11164.1203725067@pws-pc> X-Cloudmark-Analysis: v=1.0 c=1 a=Rw7lO6RaNG4A:15 a=3FTp5y5X6ml6ZCsPBftHHg==:17 a=NLZqzBF-AAAA:8 a=9aMInl9zgL1zJYC2yvwA:9 a=J3PHok2rMxGGvpvrTCMA:7 a=WhesuJnbAfE0m5E84JnxBvtdRuAA:4 a=_dQi-Dcv4p4A:10 a=XF7b4UCPwd8A:10 X-Virus-Scanned: ClamAV 0.91.2/5941/Fri Feb 22 23:18:46 2008 on bifrost X-Virus-Status: Clean This is mostly useful as a memory jogger rather than actually to save you typing a single character. However, I've added a pretty useless function to save you typing a delimiter character. (The alternative was simply to print a message saying "delimiter", which was really low tech.) It works OK so far but it does raise various issues about related things that might be got to work better. You might run across those. The change to _alternative fixes a pretty obvious bug. Presumably no one has been using it with arguments that just print a message. Index: Completion/Base/Utility/_alternative =================================================================== RCS file: /cvsroot/zsh/zsh/Completion/Base/Utility/_alternative,v retrieving revision 1.3 diff -u -r1.3 _alternative --- Completion/Base/Utility/_alternative 13 Mar 2003 10:00:21 -0000 1.3 +++ Completion/Base/Utility/_alternative 23 Feb 2008 00:04:31 -0000 @@ -75,7 +75,7 @@ done for descr in "$mesgs[@]"; do - _message -e "${descr%%:*}" "${desc#*:}" + _message -e "${descr%%:*}" "${descr#*:}" done return 1 Index: Completion/Unix/Type/_path_files =================================================================== RCS file: /cvsroot/zsh/zsh/Completion/Unix/Type/_path_files,v retrieving revision 1.26 diff -u -r1.26 _path_files --- Completion/Unix/Type/_path_files 25 Oct 2007 09:00:04 -0000 1.26 +++ Completion/Unix/Type/_path_files 23 Feb 2008 00:04:32 -0000 @@ -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 @@ 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[@]" Index: Completion/Zsh/Type/_delimiters =================================================================== RCS file: Completion/Zsh/Type/_delimiters diff -N Completion/Zsh/Type/_delimiters --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Completion/Zsh/Type/_delimiters 23 Feb 2008 00:04:32 -0000 @@ -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 Index: Completion/Zsh/Type/_globqual_delims =================================================================== RCS file: Completion/Zsh/Type/_globqual_delims diff -N Completion/Zsh/Type/_globqual_delims --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Completion/Zsh/Type/_globqual_delims 23 Feb 2008 00:04:32 -0000 @@ -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 Index: Completion/Zsh/Type/_globquals =================================================================== RCS file: Completion/Zsh/Type/_globquals diff -N Completion/Zsh/Type/_globquals --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Completion/Zsh/Type/_globquals 23 Feb 2008 00:04:32 -0000 @@ -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 Index: Completion/Zsh/Type/_history_modifiers =================================================================== RCS file: Completion/Zsh/Type/_history_modifiers diff -N Completion/Zsh/Type/_history_modifiers --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Completion/Zsh/Type/_history_modifiers 23 Feb 2008 00:04:32 -0000 @@ -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 Index: Doc/Zsh/compsys.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compsys.yo,v retrieving revision 1.203 diff -u -r1.203 compsys.yo --- Doc/Zsh/compsys.yo 25 Oct 2007 09:00:05 -0000 1.203 +++ Doc/Zsh/compsys.yo 23 Feb 2008 00:04:35 -0000 @@ -1262,6 +1262,15 @@ 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 -- Peter Stephenson Web page now at http://homepage.ntlworld.com/p.w.stephenson/