zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <pws@csr.com>
To: zsh-workers <zsh-workers@sunsite.dk>
Subject: Re: setopt globcomplete and () broken
Date: Fri, 13 Mar 2009 09:56:37 +0000	[thread overview]
Message-ID: <20090313095637.4a4a4712@news01> (raw)
In-Reply-To: <200903101818.n2AIIIFk010993@news01.csr.com>

On Tue, 10 Mar 2009 18:18:18 +0000
Peter Stephenson <pws@csr.com> 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 <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


  parent reply	other threads:[~2009-03-13  9:59 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-10 13:25 Mikael Magnusson
2009-03-10 13:51 ` Peter Stephenson
2009-03-10 17:34   ` Peter Stephenson
2009-03-10 18:04     ` Mikael Magnusson
2009-03-10 18:18       ` Peter Stephenson
2009-03-10 18:30         ` Mikael Magnusson
2009-03-11  4:22           ` Bart Schaefer
2009-03-13  9:56         ` Peter Stephenson [this message]
2009-03-13 15:08           ` Bart Schaefer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090313095637.4a4a4712@news01 \
    --to=pws@csr.com \
    --cc=zsh-workers@sunsite.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).