From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3530 invoked from network); 13 Mar 2009 09:59:09 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.5 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 13 Mar 2009 09:59:09 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 77106 invoked from network); 13 Mar 2009 09:56:54 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 13 Mar 2009 09:56:54 -0000 Received: (qmail 17661 invoked by alias); 13 Mar 2009 09:56:47 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 26723 Received: (qmail 17646 invoked from network); 13 Mar 2009 09:56:47 -0000 Received: from bifrost.dotsrc.org (130.225.254.106) by sunsite.dk with SMTP; 13 Mar 2009 09:56:47 -0000 Received: from cluster-g.mailcontrol.com (cluster-g.mailcontrol.com [208.87.233.190]) by bifrost.dotsrc.org (Postfix) with ESMTPS id AD1C980307F8 for ; Fri, 13 Mar 2009 10:56:41 +0100 (CET) Received: from cameurexb01.EUROPE.ROOT.PRI ([193.128.72.68]) by rly25g.srv.mailcontrol.com (MailControl) with ESMTP id n2D9ubf7019204 for ; Fri, 13 Mar 2009 09:56:38 GMT Received: from news01 ([10.103.143.38]) by cameurexb01.EUROPE.ROOT.PRI with Microsoft SMTPSVC(6.0.3790.3959); Fri, 13 Mar 2009 09:56:37 +0000 Date: Fri, 13 Mar 2009 09:56:37 +0000 From: Peter Stephenson To: zsh-workers Subject: Re: setopt globcomplete and () broken Message-ID: <20090313095637.4a4a4712@news01> In-Reply-To: <200903101818.n2AIIIFk010993@news01.csr.com> References: <237967ef0903100625s7e8e5908t7852ade0c1d6d8d3@mail.gmail.com> <20090310135146.30c0c794@news01> <20090310173424.1af302c5@news01> <237967ef0903101104y135e0ca6sdbd9fbe8272f2d99@mail.gmail.com> <200903101818.n2AIIIFk010993@news01.csr.com> Organization: CSR X-Mailer: Claws Mail 3.5.0 (GTK+ 2.12.8; i386-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 13 Mar 2009 09:56:37.0542 (UTC) FILETIME=[FFFAEC60:01C9A3C1] X-Scanned-By: MailControl A_08_51_00 (www.mailcontrol.com) on 10.71.0.135 X-Virus-Scanned: ClamAV 0.92.1/9103/Fri Mar 13 03:52:35 2009 on bifrost X-Virus-Status: Clean On Tue, 10 Mar 2009 18:18:18 +0000 Peter Stephenson wrote: > The extra work in this particular case is merging together glob > qualifiers passed down (e.g. "-/" becoming "*(-/)") with any that are > there on the command line. This is a rather specialised thing to do, > but you could e.g. complete "cd *(D)" and get files with dots. (It only > applies with glob_complete because otherwise what's on the command line > is a plain string and you can just use "*(-/)" as the pattern.) > This does appear to work. (In fact it appears to work even after the fix I > was going to propose for your original problem, which is encouraging.) Now CVS is back, here's the fix, which pulls together all tests for glob qualifiers into a single function for better maintainance. I've been using it for a couple of days without any obvious problems (with GLOB_COMPLETE set), but I may not have been doing the right things. Index: Completion/Unix/Type/.distfiles =================================================================== RCS file: /cvsroot/zsh/zsh/Completion/Unix/Type/.distfiles,v retrieving revision 1.20 diff -u -r1.20 .distfiles --- Completion/Unix/Type/.distfiles 21 Jul 2008 19:15:25 -0000 1.20 +++ Completion/Unix/Type/.distfiles 13 Mar 2009 09:51:35 -0000 @@ -15,6 +15,7 @@ _files _global_tags _groups +_have_glob_qual _hosts _java_class _ld_debug Index: Completion/Unix/Type/_have_glob_qual =================================================================== RCS file: Completion/Unix/Type/_have_glob_qual diff -N Completion/Unix/Type/_have_glob_qual --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Completion/Unix/Type/_have_glob_qual 13 Mar 2009 09:51:36 -0000 @@ -0,0 +1,24 @@ +#autoload + +# Test if $1 has glob qualifiers. This is partly magic, partly guesswork, +# wholly flakey. +# +# If $2 is "complete" test if the qualifiers are complete (up to the ")" +# at the end of the word), else that they are incomplete. +# Sets match, mbegin, mend to reflect their location. +# $match[1] is everything up to the start of the qualifiers themselves; +# this may therefore end in "(" or "(#q". +# $match[2] is everything at the start not counting the "(" or "(#q". +# $match[5] is the set of qualifiers themselves, not including a trailing +# parenthesis. +local complete + +[[ $2 = complete ]] && complete=")" + +[[ -z $compstate[quote] && + ( -o bareglobqual && + $1 = (#b)(((*[^\\\$]|)(\\\\)#)\()([^\)\|\~]#)$complete && + ${#match[1]} -gt 1 || + -o extendedglob && + $1 = (#b)(((*[^\\\$]|)(\\\\)#)"(#q")([^\)]#)$complete + ) ]] Index: Completion/Unix/Type/_path_files =================================================================== RCS file: /cvsroot/zsh/zsh/Completion/Unix/Type/_path_files,v retrieving revision 1.44 diff -u -r1.44 _path_files --- Completion/Unix/Type/_path_files 28 Feb 2009 07:11:31 -0000 1.44 +++ Completion/Unix/Type/_path_files 13 Mar 2009 09:51:36 -0000 @@ -14,12 +14,7 @@ # there was at least one character before the parenthesis for # a bare glob qualifier. # The later test looks for an outstanding quote. -if [[ ( -o bareglobqual && \ - $PREFIX = (#b)((*[^\\]|)(\\\\)#\()([^\)]#) && \ - ${#match[1]} -gt 1 || \ - -o extendedglob && \ - $PREFIX = (#b)((*[^\\]|)(\\\\)#"(#q")([^\)]#) \ - ) && -z $compstate[quote] ]]; then +if _have_glob_qual $PREFIX; then compset -p ${#match[1]} if [[ -o extendedglob ]] && compset -P '\#'; then _globflags @@ -88,7 +83,7 @@ else ignore=( ${(P)ignore[2]} ) fi -fi +fi # If we were given no file selection option, we behave as if we were given # a `-f'. @@ -162,14 +157,12 @@ tmp2=() for tmp1 in "$pats[@]"; do - if [[ "$tmp1" = (#b)(*[^\$])"(#q"(*)")" ]]; then - tmp2=( "$tmp2[@]" "${match[1]}(#q${sort}${match[2]})" ) - elif [[ "$tmp1" = (#b)(*[^\$])(\(\([^\|~]##\)\)) ]]; then - tmp2=( "$tmp2[@]" "${match[1]}((${sort}${match[2][3,-1]}" ) - elif [[ "$tmp1" = (#b)(*[^\$])(\([^\|~]##\)) ]]; then - tmp2=( "$tmp2[@]" "${match[1]}(${sort}${match[2][2,-1]}" ) + if _have_glob_qual "$tmp1" complete; then + # unbalanced parenthesis is correct: match[1] contains the start, + # match[5] doesn't contain the end. + tmp2+=( "${match[1]}${sort}${match[5]})" ) else - tmp2=( "$tmp2[@]" "${tmp1}(${sort})" ) + tmp2+=( "${tmp1}(${sort})" ) fi done pats=( "$tmp2[@]" ) @@ -198,31 +191,29 @@ zstyle -s ":completion:${curcontext}:" ignore-parents ignpar -if [[ -n "$compstate[pattern_match]" && - ( ( -z "$SUFFIX" && "$PREFIX" = (|*[^\$])\([^\|\~]##\) ) || - "$SUFFIX" = (|*[^\$])\([^\|\~]##\) ) ]]; then - # Copy all glob qualifiers from the line to - # the patterns used when generating matches - if [[ "$SUFFIX" = *\([^\|\~]##\) ]]; then - tmp3="${${(M)SUFFIX%\([^\|\~]##\)}[2,-2]}" - SUFFIX="${SUFFIX%\($tmp3\)}" - else - tmp3="${${(M)PREFIX%\([^\|\~]##\)}[2,-2]}" - PREFIX="${PREFIX%\($tmp3\)}" - fi - tmp2=() - for tmp1 in "$pats[@]"; do - if [[ "$tmp1" = (#b)(*[^\$])"(#q"(*)")" ]]; then - tmp2=( "$tmp2[@]" "${match[1]}(#q${tmp3}${match[2]})" ) - elif [[ "$tmp1" = (#b)(*[^\$])(\(\([^\|~]##\)\)) ]]; then - tmp2=( "$tmp2[@]" "${match[1]}((${tmp3}${match[2][3,-1]}" ) - elif [[ "$tmp1" = (#b)(*[^\$])(\([^\|~]##\)) ]]; then - tmp2=( "$tmp2[@]" "${match[1]}(${tmp3}${match[2][2,-1]}" ) +if [[ -n "$compstate[pattern_match]" ]]; then + if { [[ -z "$SUFFIX" ]] && _have_glob_qual "$PREFIX" complete } || + _have_glob_qual "$SUFFIX" complete; then + # Copy all glob qualifiers from the line to + # the patterns used when generating matches + tmp3=${match[5]} + if [[ -n "$SUFFIX" ]]; then + SUFFIX=${match[2]} else - tmp2=( "$tmp2[@]" "${tmp1}(${tmp3})" ) + PREFIX=${match[2]} fi - done - pats=( "$tmp2[@]" ) + tmp2=() + for tmp1 in "$pats[@]"; do + if _have_glob_qual "$tmp1" complete; then + # unbalanced parenthesis is correct: match[1] contains the start, + # match[5] doesn't contain the end. + tmp2+=( "${match[1]}${tmp3}${match[5]})") + else + tmp2+=( "${tmp1}(${tmp3})" ) + fi + done + pats=( "$tmp2[@]" ) + fi fi # We get the prefix and the suffix from the line and save the whole -- Peter Stephenson Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070