zsh-workers
 help / color / mirror / code / Atom feed
* setopt globcomplete and () broken
@ 2009-03-10 13:25 Mikael Magnusson
  2009-03-10 13:51 ` Peter Stephenson
  0 siblings, 1 reply; 9+ messages in thread
From: Mikael Magnusson @ 2009-03-10 13:25 UTC (permalink / raw)
  To: zsh-workers

This is something that has been broken forever, but I never bothered
to look into exactly what broke it in my config. Today I got annoyed
enough though.

zsh -f
% autoload compinit; compinit
% mkdir newdir; cd newdir
% touch '()' '().'
% touch <tab>
% touch \(\)<tab>
\(\)   \(\).
% setopt globcomplete
% touch <tab>
% touch \(\)<tab>
# nothing appears

I can only reproduce it with a pair of parentheses, just ( or )
doesn't trigger it, but text can appear between them and still trigger
it. The oldest version I tried was 4.2.5 and the newest some days old
cvs.

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: setopt globcomplete and () broken
  2009-03-10 13:25 setopt globcomplete and () broken Mikael Magnusson
@ 2009-03-10 13:51 ` Peter Stephenson
  2009-03-10 17:34   ` Peter Stephenson
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Stephenson @ 2009-03-10 13:51 UTC (permalink / raw)
  To: zsh-workers

On Tue, 10 Mar 2009 14:25:16 +0100
Mikael Magnusson <mikachu@gmail.com> wrote:
> This is something that has been broken forever, but I never bothered
> to look into exactly what broke it in my config. Today I got annoyed
> enough though.
> 
> zsh -f
> % autoload compinit; compinit
> % mkdir newdir; cd newdir
> % touch '()' '().'
> % touch <tab>
> % touch \(\)<tab>
> \(\)   \(\).
> % setopt globcomplete
> % touch <tab>
> % touch \(\)<tab>
> # nothing appears
> 
> I can only reproduce it with a pair of parentheses, just ( or )
> doesn't trigger it, but text can appear between them and still trigger
> it. The oldest version I tried was 4.2.5 and the newest some days old
> cvs.

The following chunk of code in guess-where around line 201 is triggering:
it's looking for glob qualifiers.  We need a test that the parentheses
aren't quoted; we could have '()' or "()" or $'()' or \(\), or some
mixture, possibly with text in between.  There is a slightly better test
higher up, around line 17 (which correctly didn't trigger): that's newer
code that I added when completing glob qualifiers.  (The chunk of code
below isn't completing them, it's trying to ensure they get applied.)
Possibly copying the newer test here or putting it into a separate function
would help, but I will wait for any cries of enlightenment before I do
anything.

It would be quite nice to have a test for the shell to decide "is character
N in this command line argument a token or a metacharacter?" which isn't so
much more than the context lex horrors already do...  I suppose
parse-partial-sexp is out of the question.

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]}" )
    else
      tmp2=( "$tmp2[@]" "${tmp1}(${tmp3})" )
    fi
  done
  pats=( "$tmp2[@]" )
fi

-- 
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


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: setopt globcomplete and () broken
  2009-03-10 13:51 ` Peter Stephenson
@ 2009-03-10 17:34   ` Peter Stephenson
  2009-03-10 18:04     ` Mikael Magnusson
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Stephenson @ 2009-03-10 17:34 UTC (permalink / raw)
  To: zsh-workers

On Tue, 10 Mar 2009 13:51:46 +0000
Peter Stephenson <pws@csr.com> wrote:
>     elif [[ "$tmp1" = (#b)(*[^\$])(\(\([^\|~]##\)\)) ]]; then
>       tmp2=( "$tmp2[@]" "${match[1]}((${tmp3}${match[2][3,-1]}" )

I thought I was on the way to understanding what was going on here, but
this attempt to match some form of glob qualifiers has stumped me.  Why are
we specially matching a pattern ending with glob qualifiers wrapped in
double parentheses?  What we're matching against, $tmp1, comes from patterns
supplied to _files or _path_files as an argument; I can't see any sign the
double parentheses are used, and the expansion manual says

  A glob subexpression that would normally be taken as glob qualifiers, for
  example (^x), can be forced to be treated as part of the glob pattern by
  doubling the parentheses, in this case producing ((^x)).

Yet we are treating it as if it's a glob expression ($tmp3 is the
new glob qualifier we are trying to insinuate into the list).

Can I simply hold my breath until it goes away?

-- 
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


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: setopt globcomplete and () broken
  2009-03-10 17:34   ` Peter Stephenson
@ 2009-03-10 18:04     ` Mikael Magnusson
  2009-03-10 18:18       ` Peter Stephenson
  0 siblings, 1 reply; 9+ messages in thread
From: Mikael Magnusson @ 2009-03-10 18:04 UTC (permalink / raw)
  To: zsh-workers

2009/3/10 Peter Stephenson <pws@csr.com>:
> On Tue, 10 Mar 2009 13:51:46 +0000
> Peter Stephenson <pws@csr.com> wrote:
>>     elif [[ "$tmp1" = (#b)(*[^\$])(\(\([^\|~]##\)\)) ]]; then
>>       tmp2=( "$tmp2[@]" "${match[1]}((${tmp3}${match[2][3,-1]}" )
>
> I thought I was on the way to understanding what was going on here, but
> this attempt to match some form of glob qualifiers has stumped me.  Why are
> we specially matching a pattern ending with glob qualifiers wrapped in
> double parentheses?  What we're matching against, $tmp1, comes from patterns
> supplied to _files or _path_files as an argument; I can't see any sign the
> double parentheses are used, and the expansion manual says
>
>  A glob subexpression that would normally be taken as glob qualifiers, for
>  example (^x), can be forced to be treated as part of the glob pattern by
>  doubling the parentheses, in this case producing ((^x)).
>
> Yet we are treating it as if it's a glob expression ($tmp3 is the
> new glob qualifier we are trying to insinuate into the list).
>
> Can I simply hold my breath until it goes away?

If I delete that whole paragraph of code, my completion works as I
want, but I break what it wanted to fix,
http://www.zsh.org/mla/workers/2000/msg02437.html
http://www.zsh.org/mla/workers/2000/msg02455.html
http://www.zsh.org/mla/workers/2000/msg02456.html
http://www.zsh.org/mla/workers/2000/msg02458.html

If I unsetopt globcomplete, I can ls *zshenv(D)<tab> with the
paragraph deleted though, so it all seems a bit crazy to me. I thought
globcomplete was about completing things with patterns that weren't
files in the first place, so why do glob qualifiers come into the
picture at all? ie what I want to do is *2png<tab> and find my ps2png
program, I don't see how (D) would ever fit in there. I guess some
crazy people might have binaries starting with a ., but apart from the
sorting flags, none of the other glob qualifiers make any sense here,
do they?

And when completing actual files, why would globcomplete mean
_path_files has to do extra work instead of just expanding the
pattern? Put differently, why does globcomplete affect _path_files at
all? Hm, if i touch cat cbt, then with globcomplete on, c*t<tab> lets
me cycle between them, while with it off, it just inserts both
matches. (this is with
zstyle ':completion:*' completer _oldlist _complete _correct
)

In summary, I guess I have no idea how any of this works :).

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: setopt globcomplete and () broken
  2009-03-10 18:04     ` Mikael Magnusson
@ 2009-03-10 18:18       ` Peter Stephenson
  2009-03-10 18:30         ` Mikael Magnusson
  2009-03-13  9:56         ` Peter Stephenson
  0 siblings, 2 replies; 9+ messages in thread
From: Peter Stephenson @ 2009-03-10 18:18 UTC (permalink / raw)
  To: zsh-workers

Mikael Magnusson wrote:
> If I unsetopt globcomplete, I can ls *zshenv(D)<tab> with the
> paragraph deleted though, so it all seems a bit crazy to me.

Are you sure that's not going through _expand?  If I remove _expand from
the list of completers, I don't get completions for things like *zshe*(D)
unless glob_complete is set.

> I thought
> globcomplete was about completing things with patterns that weren't
> files in the first place, so why do glob qualifiers come into the
> picture at all?

They're not *necessarily* files, but they could be anything; and
if they are files, then globcomplete means exactly what it says,
complete based on full file glob expressions.

> And when completing actual files, why would globcomplete mean
> _path_files has to do extra work instead of just expanding the
> pattern?

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.)

-- 
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


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: setopt globcomplete and () broken
  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
  1 sibling, 1 reply; 9+ messages in thread
From: Mikael Magnusson @ 2009-03-10 18:30 UTC (permalink / raw)
  To: zsh-workers

2009/3/10 Peter Stephenson <pws@csr.com>:
> Mikael Magnusson wrote:
>> If I unsetopt globcomplete, I can ls *zshenv(D)<tab> with the
>> paragraph deleted though, so it all seems a bit crazy to me.
>
> Are you sure that's not going through _expand?  If I remove _expand from
> the list of completers, I don't get completions for things like *zshe*(D)
> unless glob_complete is set.

Well, as i wrote further down my completer list is _oldlist _complete
_correct, i don't know if that is a yes or a no :).

>> I thought
>> globcomplete was about completing things with patterns that weren't
>> files in the first place, so why do glob qualifiers come into the
>> picture at all?
>
> They're not *necessarily* files, but they could be anything; and
> if they are files, then globcomplete means exactly what it says,
> complete based on full file glob expressions.

Okay, so I was testing if ls --*e(#e)<tab> worked with globcomplete
on, which it does (ie it only lists options ending in 'e'). But since
I forgot which flag meant end of string, i pressed tab at the #, but
got
_path_files:25: command not found: _globflags
printed 5 or 6 times, if I run autoload _globflags it works. This
seems odd to me since _globquals seems to work without any special
treatment.

>> And when completing actual files, why would globcomplete mean
>> _path_files has to do extra work instead of just expanding the
>> pattern?
>
> 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.)

Okay, there is probably a whole level of stuff going on here that I
wasn't even aware of.

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: setopt globcomplete and () broken
  2009-03-10 18:30         ` Mikael Magnusson
@ 2009-03-11  4:22           ` Bart Schaefer
  0 siblings, 0 replies; 9+ messages in thread
From: Bart Schaefer @ 2009-03-11  4:22 UTC (permalink / raw)
  To: zsh-workers

There are two patch hunks in here, one all the way at the end.

On Mar 10,  1:51pm, Peter Stephenson wrote:
} Subject: Re: setopt globcomplete and () broken
}
} On Tue, 10 Mar 2009 14:25:16 +0100
} Mikael Magnusson <mikachu@gmail.com> wrote:
} > % touch '()' '().'
} > % touch <tab>
} > % touch \(\)<tab>
} > \(\)   \(\).
} > % setopt globcomplete
} > % touch <tab>
} > % touch \(\)<tab>
} > # nothing appears
} 
} The following chunk of code in guess-where around line 201 is triggering:
} it's looking for glob qualifiers.  We need a test that the parentheses
} aren't quoted; we could have '()' or "()" or $'()' or \(\), or some
} mixture, possibly with text in between.
} 
} if [[ -n "$compstate[pattern_match]" &&

Note that this first test is true when globcomplete is set.  The only
other time it can be true is if we somehow come through here via one of 
_correct or _approximate (or someone's personal completer function that
attempts something similar).

}       ( ( -z "$SUFFIX" && "$PREFIX" = (|*[^\$])\([^\|\~]##\) ) ||
}         "$SUFFIX" =  (|*[^\$])\([^\|\~]##\) ) ]]; then

Except for the insanely complicated case where an (e:...:) qualifier
has an expression with backslashes, which I'll bet this has never
really handled anyway, I think the following may deal with it:

Index: Completion/Unix/Type/_path_files
===================================================================
diff -c -r1.20 _path_files
--- _path_files	28 Feb 2009 07:13:24 -0000	1.20
+++ _path_files	11 Mar 2009 03:34:33 -0000
@@ -199,8 +199,8 @@
 zstyle -s ":completion:${curcontext}:" ignore-parents ignpar
 
 if [[ -n "$compstate[pattern_match]" &&
-      ( ( -z "$SUFFIX" && "$PREFIX" = (|*[^\$])\([^\|\~]##\) ) ||
-        "$SUFFIX" =  (|*[^\$])\([^\|\~]##\) ) ]]; then
+      ( ( -z "$SUFFIX" && "$PREFIX" = (|*[^\$])\([^\|\~\\]##\) ) ||
+        "$SUFFIX" = (|*[^\$])\([^\|\~\\]##\) ) ]]; then
   # Copy all glob qualifiers from the line to
   # the patterns used when generating matches
   if [[ "$SUFFIX" = *\([^\|\~]##\) ]]; then


I think that will cover the majority of cases, but let's explore the
rathole PWS has gone down just a bit farther.


On Mar 10,  5:34pm, Peter Stephenson wrote:
} Subject: Re: setopt globcomplete and () broken
}
} On Tue, 10 Mar 2009 13:51:46 +0000
} Peter Stephenson <pws@csr.com> wrote:
} >     elif [[ "$tmp1" = (#b)(*[^\$])(\(\([^\|~]##\)\)) ]]; then
} >       tmp2=( "$tmp2[@]" "${match[1]}((${tmp3}${match[2][3,-1]}" )
} 
} I thought I was on the way to understanding what was going on here, but
} this attempt to match some form of glob qualifiers has stumped me.  Why are
} we specially matching a pattern ending with glob qualifiers wrapped in
} double parentheses?

That seems to be from zsh-workers/9191, and Sven wrote it that way
right from the beginning.  Note it used to be inside a test for whether
the "sort" style was set; I haven't tracked down when that changed.

} Can I simply hold my breath until it goes away?

Or until Sven comes back, I suppose.


On Mar 10,  7:04pm, Mikael Magnusson wrote:
} Subject: Re: setopt globcomplete and () broken
}
} If I delete that whole paragraph of code, my completion works as I
} want

Not surprising, see my first remark about $compstate[pattern_match].


On Mar 10,  6:18pm, Peter Stephenson wrote:
} Subject: Re: setopt globcomplete and () broken
}
} Mikael Magnusson wrote:
} > And when completing actual files, why would globcomplete mean
} > _path_files has to do extra work instead of just expanding the
} > pattern?
} 
} 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.

Right, but in this case there is no glob qualifier, just a real file
name with parens in it.  So what we really want to do is avoid that
mess entirely, isn't it?  Worrying about doubled parens is a tangent.


On Mar 10,  7:30pm, Mikael Magnusson wrote:
} Subject: Re: setopt globcomplete and () broken
}
} > Are you sure that's not going through _expand? If I remove _expand
} > from the list of completers, I don't get completions for things like
} > *zshe*(D) unless glob_complete is set.
} 
} Well, as i wrote further down my completer list is _oldlist _complete
} _correct, i don't know if that is a yes or a no :).

It completes for me without _expand as well.  The _complete_debug
trace is too long and call _path_files too many times to work out
exactly what the call sequence is, but it has something to do with
the _match completer.

} _path_files:25: command not found: _globflags
} printed 5 or 6 times, if I run autoload _globflags it works. This
} seems odd to me since _globquals seems to work without any special
} treatment.

The _globflags file in the source lacks a "#compdef" or "#autoload"
line at the top.

Index: Completion/Zsh/Type/_globflags
===================================================================
retrieving revision 1.1
diff -c -r1.1 _globflags
--- _globflags	23 Nov 2008 18:26:27 -0000	1.1
+++ _globflags	11 Mar 2009 04:21:01 -0000
@@ -1,3 +1,5 @@
+#autoload
+
 local ret=1
 local -a flags
 

-- 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: setopt globcomplete and () broken
  2009-03-10 18:18       ` Peter Stephenson
  2009-03-10 18:30         ` Mikael Magnusson
@ 2009-03-13  9:56         ` Peter Stephenson
  2009-03-13 15:08           ` Bart Schaefer
  1 sibling, 1 reply; 9+ messages in thread
From: Peter Stephenson @ 2009-03-13  9:56 UTC (permalink / raw)
  To: zsh-workers

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


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: setopt globcomplete and () broken
  2009-03-13  9:56         ` Peter Stephenson
@ 2009-03-13 15:08           ` Bart Schaefer
  0 siblings, 0 replies; 9+ messages in thread
From: Bart Schaefer @ 2009-03-13 15:08 UTC (permalink / raw)
  To: zsh-workers

On Mar 13,  9:56am, Peter Stephenson wrote:
} Subject: Re: setopt globcomplete and () broken
}
} Now CVS is back, here's the fix, which pulls together all tests for glob
} qualifiers into a single function for better maintainance.

I wonder if there's anywhere else we should be using this.

I've committed only the second patch from 26713, as yours supercedes the
first one.


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2009-03-13 15:10 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-10 13:25 setopt globcomplete and () broken 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
2009-03-13 15:08           ` Bart Schaefer

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).