zsh-workers
 help / color / mirror / code / Atom feed
* Re: BUG: Matching cause character to be deleted.
@ 2000-04-27  6:57 Felix Rosencrantz
  0 siblings, 0 replies; 4+ messages in thread
From: Felix Rosencrantz @ 2000-04-27  6:57 UTC (permalink / raw)
  To: zsh-workers

I pulled the latest source code and have been using the new matching control
specifications all day.  So far it looks really great!  Also, the churning
issue was solved with the empty matching spec. But it was also fixed by the
subsequent performance patch.  So I've dropped the empty matching spec from my
matcher-list, and so far things are working well.

I'm quite happy with the changes.

Thanks Sven!

-FR

__________________________________________________
Do You Yahoo!?
Talk to your friends online and get email alerts with Yahoo! Messenger.
http://im.yahoo.com/


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

* Re: BUG: Matching cause character to be deleted.
@ 2000-04-26  6:52 Sven Wischnowsky
  0 siblings, 0 replies; 4+ messages in thread
From: Sven Wischnowsky @ 2000-04-26  6:52 UTC (permalink / raw)
  To: zsh-workers


I wrote:

> Felix Rosencrantz wrote:
> 
> ...
> 
> > It would nice if it was possible to specify gaps between characters as anchors,
> > even if it would make it more difficult to understand matching specifications.
> > (Though, I'm challenged by just writing specifications, I'm not offering to
> > modify the code. )
> 
> (I can easily understand that you are not offering to modify the
> code... sigh.)
> 
> If at all, I would do that only for very simple cases, e.g.:
> 
>   r:|[^A-Z]|[A-Z]=*
> 
> (Note the two `|'s, any suggestions for a better syntax?)
> 
> This would mean that the anchor `[^A-Z]|[A-Z]' is the gap between a
> non-uppercase or an uppercase letter. The matching itself doesn't look 
> too hard. The handling of the clines may be a problem unless... hm.
> 
> This would treat the `[^A-Z]' like a left-hand anchor to the
> right-hand anchor. I think I'll just have to try it.

This was the idea that made it look simple enough to try it. And even
if the patch looks quite big, it isn't.

The syntax is: `r:<lanchor>||<ranchor>=*' (see the manual for a better 
description and examples). The <lanchor> is only compared to the trial 
completion string and the whole thing means that the completion code
may insert characters before <ranchor>, but only if that is preceded
by <lanchor>. I think the syntax is quite good, btw. The `||' is the
`gap', or, when compared with the normal form, an empty line-pattern.

Let's try it.

Bye
 Sven

P.S.: I've even change _x_color...

Index: Completion/X/_x_color
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/X/_x_color,v
retrieving revision 1.1.1.8
diff -u -r1.1.1.8 _x_color
--- Completion/X/_x_color	2000/03/23 04:19:31	1.1.1.8
+++ Completion/X/_x_color	2000/04/26 06:51:47
@@ -31,5 +31,5 @@
 fi
 
 _wanted colors expl 'color specification' \
-    compadd "$@" -M 'm:{a-z}={A-Z} m:-=\  r:|[ A-Z0-9]=* r:|=*' - \
+    compadd "$@" -M 'm:{a-z}={A-Z} m:-=\  r:[^ A-Z0-9]||[ A-Z0-9]=* r:|=*' - \
             "$_color_cache[@]"
Index: Doc/Zsh/compwid.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compwid.yo,v
retrieving revision 1.5
diff -u -r1.5 compwid.yo
--- Doc/Zsh/compwid.yo	2000/04/18 07:36:56	1.5
+++ Doc/Zsh/compwid.yo	2000/04/26 06:51:47
@@ -764,21 +764,30 @@
 Here, var(lpat) is a pattern that matches on the command line,
 corresponding to var(tpat) which matches in the trial completion.
 )
-xitem(tt(l:)var(anchor)tt(|)var(lpat)tt(=)var(tpat))
-item(tt(L:)var(anchor)tt(|)var(lpat)tt(=)var(tpat))(
+xitem(tt(l:)var(lanchor)tt(|)var(lpat)tt(=)var(tpat))
+xitem(tt(L:)var(lanchor)tt(|)var(lpat)tt(=)var(tpat))
+xitem(tt(l:)var(lanchor)tt(||)var(ranchor)tt(=)var(tpat))
+item(tt(L:)var(lanchor)tt(||)var(ranchor)tt(=)var(tpat))(
 These letters are for patterns that are anchored by another pattern on
 the left side. Matching for var(lpat) and var(tpat) is as for tt(m) and
 tt(M), but the pattern var(lpat) matched on the command line must be
-preceeded by the pattern var(anchor).  The var(anchor) can be blank to
+preceeded by the pattern var(lanchor).  The var(lanchor) can be blank to
 anchor the match to the start of the command line string; otherwise the
 anchor can occur anywhere, but must match in both the command line and
 trial completion strings.
+
+If no var(lpat) is given, but a var(ranchor), this matches the gap
+between substrings matched by var(lanchor) an var(ranchor). Unlike
+var(lanchor), the var(ranchor) only needs to match the trial
+completion string.
 )
-xitem(tt(r:)var(lpat)tt(|)var(anchor)tt(=)var(tpat))
-item(tt(R:)var(lpat)tt(|)var(anchor)tt(=)var(tpat))(
+xitem(tt(r:)var(lpat)tt(|)var(ranchor)tt(=)var(tpat))
+xitem(tt(R:)var(lpat)tt(|)var(ranchor)tt(=)var(tpat))
+xitem(tt(r:)var(lanchor)tt(||)var(ranchor)tt(=)var(tpat))
+item(tt(R:)var(lanchor)tt(||)var(ranchor)tt(=)var(tpat))(
 As tt(l) and tt(L) with the difference that the command line and trial
 completion patterns are anchored on the right side.  Here an empty
-var(anchor) forces the match to the end of the command line string.
+var(ranchor) forces the match to the end of the command line string.
 )
 enditem()
 
@@ -902,6 +911,29 @@
 complete tt(veryverylongfile.c) rather than tt(veryverylongheader.h)
 with the above in effect, you can just type tt(very.c) before attempting
 completion.
+
+The specifications with both a left and a right anchor are useful to
+complete partial words whose parts are not really separated by some
+special character. For example, in some places strings have to be
+completed that are formed `tt(LikeThis)' (i.e. the separate parts are
+determined by a leading uppercase letter) or maybe one has to
+complete strings with trailing numbers. Here one could use the simple
+form with only one anchor as in:
+
+example(compadd -M 'r:|[A-Z0-9]=* r:|=*' LikeTHIS FooHoo foo123 bar234)
+
+But with this, the string `tt(H)' would be completed to `tt(FooHoo)'
+em(and) tt(LikeTHIS) and `tt(2)' would be completed to the other two
+strings because characters can be inserted before every uppercase
+letter and digit. To avoid this one would use:
+
+example(compadd -M 'r:[^A-Z0-9]||[A-Z0-9]=* r:|=*' \
+    LikeTHIS FooHoo foo123 bar234)
+
+By using these two anchors, a `tt(H)' matches only uppercase `H's that 
+are immediately preceded by something matching the left anchor
+`tt([^A-Z0-9])'. The effect is, of course, that `tt(H)' matches only
+the string `tt(FooHoo)', a `tt(2)' matches only `tt(bar234)' and so on.
 
 When using the completion system (see
 ifzman(zmanref(zshcompsys))\
Index: Src/Zle/complete.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/complete.c,v
retrieving revision 1.3
diff -u -r1.3 complete.c
--- Src/Zle/complete.c	2000/04/17 11:17:10	1.3
+++ Src/Zle/complete.c	2000/04/26 06:51:48
@@ -182,12 +182,15 @@
 {
     Cmatcher ret = NULL, r = NULL, n;
     Cpattern line, word, left, right;
-    int fl, ll, wl, lal, ral, err;
+    int fl, ll, wl, lal, ral, err, both;
 
     if (!*s)
 	return NULL;
 
     while (*s) {
+	lal = ral = both = 0;
+	left = right = NULL;
+
 	while (*s && inblank(*s)) s++;
 
 	if (!*s) break;
@@ -216,6 +219,10 @@
 	    left = parse_pattern(name, &s, &lal, '|', &err);
 	    if (err)
 		return pcm_err;
+
+	    if ((both = (*s == '|')))
+		s++;
+
 	    if (!*s || !*++s) {
 		zwarnnam(name, "missing line pattern", NULL, 0);
 		return pcm_err;
@@ -227,6 +234,12 @@
 			     &err);
 	if (err)
 	    return pcm_err;
+	if (both) {
+	    right = line;
+	    ral = ll;
+	    line = NULL;
+	    ll = 0;
+	}
 	if ((fl & CMF_RIGHT) && (!*s || !*++s)) {
 	    zwarnnam(name, "missing right anchor", NULL, 0);
 	} else if (!(fl & CMF_RIGHT)) {
@@ -237,6 +250,13 @@
 	    s++;
 	}
 	if (fl & CMF_RIGHT) {
+	    if (*s == '|') {
+		left = line;
+		lal = ll;
+		line = NULL;
+		ll = 0;
+		s++;
+	    }
 	    right = parse_pattern(name, &s, &ral, '=', &err);
 	    if (err)
 		return pcm_err;
Index: Src/Zle/compmatch.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/compmatch.c,v
retrieving revision 1.8
diff -u -r1.8 compmatch.c
--- Src/Zle/compmatch.c	2000/04/26 06:45:50	1.8
+++ Src/Zle/compmatch.c	2000/04/26 06:51:48
@@ -57,11 +57,9 @@
 	     a->llen == b->llen && a->wlen == b->wlen &&
 	     (!a->llen || cmp_cpatterns(a->line, b->line)) &&
 	     (a->wlen <= 0 || cmp_cpatterns(a->word, b->word)) &&
-	     (!(a->flags & CMF_LEFT) ||
-	      (a->lalen == b->lalen &&
-	       (!a->lalen || cmp_cpatterns(a->left, b->left)))) &&
-	     (!(a->flags & CMF_RIGHT) ||
-	      (a->ralen == b->ralen &&
+	     (!(a->flags & (CMF_LEFT | CMF_RIGHT)) ||
+	      (a->lalen == b->lalen && a->ralen == b->ralen &&
+	       (!a->lalen || cmp_cpatterns(a->left, b->left)) &&
 	       (!a->ralen || cmp_cpatterns(a->right, b->right))))));
 }
 
@@ -514,29 +512,32 @@
 		    continue;
 
 		if (mp->wlen < 0) {
-		    int both, loff, aoff, llen, alen, zoff, moff, ct, ict;
+		    int both, loff, aoff, llen, alen, zoff, moff, ct, ict, aol;
 		    char *tp, savl = '\0', savw;
-		    Cpattern ap;
+		    Cpattern ap, aop;
 
 		    /* This is for `*' patterns, first initialise some
 		     * local variables. */
 		    llen = mp->llen;
-		    alen = (mp->flags & CMF_LEFT ? mp->lalen : mp->ralen);
-
+		    if (mp->flags & CMF_LEFT) {
+			alen = mp->lalen; aol = mp->ralen;
+		    } else {
+			alen = mp->ralen; aol = mp->lalen;
+		    }
 		    /* Give up if we don't have enough characters for the
 		     * line-string and the anchor. */
-		    if (ll < llen + alen || lw < alen)
+		    if (ll < llen + alen || lw < alen + aol)
 			continue;
 
 		    if (mp->flags & CMF_LEFT) {
-			ap = mp->left; zoff = 0; moff = alen;
+			ap = mp->left; zoff = 0; moff = alen; aop = mp->right;
 			if (sfx) {
 			    both = 0; loff = -llen; aoff = -(llen + alen);
 			} else {
 			    both = 1; loff = alen; aoff = 0;
 			}
 		    } else {
-			ap = mp->right; zoff = alen; moff = 0;
+			ap = mp->right; zoff = alen; moff = 0; aop = mp->left;
 			if (sfx) {
 			    both = 1; loff = -(llen + alen); aoff = -alen;
 			} else {
@@ -548,9 +549,11 @@
 			continue;
 		    if (ap) {
 			if (!pattern_match(ap, l + aoff, NULL, NULL) ||
-			    (both && (!pattern_match(ap, w + aoff, NULL, NULL) ||
-				      !match_parts(l + aoff, w + aoff, alen,
-						   part))))
+			    (both &&
+			     (!pattern_match(ap, w + aoff, NULL, NULL) ||
+			      (aol && !pattern_match(aop, w + aoff - aol,
+						     NULL, NULL)) ||
+			      !match_parts(l + aoff, w + aoff, alen, part))))
 				continue;
 		    } else if (!both || il || iw)
 			continue;
@@ -566,9 +569,13 @@
 			 tp += add, ct++, ict--) {
 			if ((both &&
 			     (!ap || !test ||
-			      !pattern_match(ap, tp + aoff, NULL, NULL))) ||
+			      !pattern_match(ap, tp + aoff, NULL, NULL) ||
+			      (aol && !pattern_match(aop, tp + aoff - aol,
+						     NULL, NULL)))) ||
 			    (!both &&
 			     pattern_match(ap, tp - moff, NULL, NULL) &&
+			     (!aol || pattern_match(aop, tp - moff - aol,
+						    NULL, NULL)) &&
 			     match_parts(l + aoff , tp - moff, alen, part))) {
 			    if (sfx) {
 				savw = tp[-zoff];
@@ -699,28 +706,36 @@
 		    }
 		    if (mp->flags & CMF_LEFT) {
 			/* Try to match the left anchor, if any. */
-			if (til < mp->lalen || tiw < mp->lalen)
+			if (til < mp->lalen || tiw < mp->lalen + mp->ralen)
 			    continue;
 			else if (mp->left)
 			    t = pattern_match(mp->left, tl - mp->lalen,
 					      NULL, NULL) &&
 				pattern_match(mp->left, tw - mp->lalen,
-					      NULL, NULL);
+					      NULL, NULL) &&
+				(!mp->ralen ||
+				 pattern_match(mp->right,
+					       tw - mp->lalen - mp->ralen,
+					       NULL, NULL));
 			else
 			    t = (!sfx && !il && !iw);
 		    }
 		    if (mp->flags & CMF_RIGHT) {
 			/* Try to match the right anchor, if any. */
 			if (tll < mp->llen + mp->ralen ||
-			    tlw < mp->wlen + mp->ralen)
+			    tlw < mp->wlen + mp->ralen + mp->lalen)
 			    continue;
-			else if (mp->left)
+			else if (mp->right)
 			    t = pattern_match(mp->right,
 					      tl + mp->llen - mp->ralen,
 					      NULL, NULL) &&
 				pattern_match(mp->right,
 					      tw + mp->wlen - mp->ralen,
-					      NULL, NULL);
+					      NULL, NULL) &&
+				(!mp->lalen ||
+				 pattern_match(mp->left, tw + mp->wlen -
+					       mp->ralen - mp->lalen,
+					       NULL, NULL));
 			else
 			    t = (sfx && !il && !iw);
 		    }
@@ -1044,8 +1059,11 @@
 	for (t = 0, ms = bmatchers; ms && !t; ms = ms->next) {
 	    mp = ms->matcher;
 	    if (mp && mp->flags == CMF_RIGHT && mp->wlen < 0 &&
-		!mp->llen && len >= mp->ralen && mp->ralen &&
-		pattern_match(mp->right, str, NULL, NULL)) {
+		!mp->llen && len >= mp->ralen + mp->lalen && mp->ralen &&
+		pattern_match(mp->right, str, NULL, NULL) &&
+		(!mp->lalen ||
+		 ((str - p) >= mp->lalen &&
+		  pattern_match(mp->left, str - mp->lalen, NULL, NULL)))) {
 		int olen = str - p, llen;
 
 		/* We found an anchor, create a new cline. The NEW flag

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


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

* Re: BUG: Matching cause character to be deleted.
@ 2000-04-25 14:08 Sven Wischnowsky
  0 siblings, 0 replies; 4+ messages in thread
From: Sven Wischnowsky @ 2000-04-25 14:08 UTC (permalink / raw)
  To: zsh-workers


Felix Rosencrantz wrote:

> Since, I offered to add the example to the documentation,
> I was starting to look at the suggested matching specification that
> Sven suggested for dealing with anchors between numbers and upper case
> letters, so f2 could match file2, and IR2 could match IndianRed2.
> 
> I found this bug, which is pruned down.
> 
> myprompt@ zsh -f
> host% mkdir j
> host% touch j/{BW,UWB,W} 
> host% bindkey -e; autoload -U compinit; compinit -D
> host% zstyle ':completion:*:complete:*' matcher-list 'r:|[A-Z0-9]=*'
> host% ls j/W<TAB>  #Tab deletes the W, so the line looks like this:
> host% ls j/ 

Oh well. This is a result of 9870. I have to rethink this... (probably 
together with the other possible changes to the matching stuff, if
any).

> Though, the matching specification suggested seems to comes pretty close to
> what I want, it still has some odd behaviors when handling filenames
> that contain upper case words, like ABCdef.  Matching seems to match in the
> middle of words, which doesn't quite feel right.

I fear I don't exactly understand what you say, but I'm pretty sure I
know what you mean ;-)

That's why I sent that follow-up to my reply...

> It would nice if it was possible to specify gaps between characters as anchors,
> even if it would make it more difficult to understand matching specifications.
> (Though, I'm challenged by just writing specifications, I'm not offering to
> modify the code. )

(I can easily understand that you are not offering to modify the
code... sigh.)

If at all, I would do that only for very simple cases, e.g.:

  r:|[^A-Z]|[A-Z]=*

(Note the two `|'s, any suggestions for a better syntax?)

This would mean that the anchor `[^A-Z]|[A-Z]' is the gap between a
non-uppercase or an uppercase letter. The matching itself doesn't look 
too hard. The handling of the clines may be a problem unless... hm.

This would treat the `[^A-Z]' like a left-hand anchor to the
right-hand anchor. I think I'll just have to try it.

Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


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

* BUG: Matching cause character to be deleted.
@ 2000-04-21  0:47 Felix Rosencrantz
  0 siblings, 0 replies; 4+ messages in thread
From: Felix Rosencrantz @ 2000-04-21  0:47 UTC (permalink / raw)
  To: zsh-workers

Since, I offered to add the example to the documentation,
I was starting to look at the suggested matching specification that
Sven suggested for dealing with anchors between numbers and upper case
letters, so f2 could match file2, and IR2 could match IndianRed2.

I found this bug, which is pruned down.

myprompt@ zsh -f
host% mkdir j
host% touch j/{BW,UWB,W} 
host% bindkey -e; autoload -U compinit; compinit -D
host% zstyle ':completion:*:complete:*' matcher-list 'r:|[A-Z0-9]=*'
host% ls j/W<TAB>  #Tab deletes the W, so the line looks like this:
host% ls j/ 


Though, the matching specification suggested seems to comes pretty close to
what I want, it still has some odd behaviors when handling filenames
that contain upper case words, like ABCdef.  Matching seems to match in the
middle of words, which doesn't quite feel right.

It would nice if it was possible to specify gaps between characters as anchors,
even if it would make it more difficult to understand matching specifications.
(Though, I'm challenged by just writing specifications, I'm not offering to
modify the code. )

-FR


__________________________________________________
Do You Yahoo!?
Send online invitations with Yahoo! Invites.
http://invites.yahoo.com


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

end of thread, other threads:[~2000-04-27  6:57 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-04-27  6:57 BUG: Matching cause character to be deleted Felix Rosencrantz
  -- strict thread matches above, loose matches on Subject: below --
2000-04-26  6:52 Sven Wischnowsky
2000-04-25 14:08 Sven Wischnowsky
2000-04-21  0:47 Felix Rosencrantz

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