Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: completion matching



I can't easily find the message, but this was discussed when Felix
added the matching control tests. Currently neither `__listbe' nor
`_no_listbe' nor `nononolistbe' can be completed. I said that I once
tried this (still can't remember if this was changed before the first
release) and that I found problems with it. But it seems as with
match_str() has changed to allow such things, so this patch adds the
match spec characters [bBeE]. b and B are like l and L, but one can't
give an anchor -- the anchor is implicitly the beginning of the trial
completion. Note the difference: l and L match the anchor to both the
trial completion and the word on the line, b and B only the former.
e and E, of course are like r and R with an implicit anchor to the
end.

But of course, `_n_o_listbe' still cannot be completed (that would be
a completely different and a lot more complicated thing; and I'm not
sure if I would like it because it looks like a great source for
infinite recursions).

Bye
 Sven

Index: Completion/Core/_options
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Core/_options,v
retrieving revision 1.2
diff -u -r1.2 _options
--- Completion/Core/_options	2000/05/31 09:38:26	1.2
+++ Completion/Core/_options	2000/06/19 10:39:11
@@ -5,4 +5,4 @@
 local expl
 
 _wanted zsh-options expl 'zsh option' \
-    compadd "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -k options
+    compadd "$@" -M 'B:[nN][oO]= M:_= M:{A-Z}={a-z}' -k options
Index: Completion/Core/_set_options
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Core/_set_options,v
retrieving revision 1.2
diff -u -r1.2 _set_options
--- Completion/Core/_set_options	2000/05/31 09:38:26	1.2
+++ Completion/Core/_set_options	2000/06/19 10:39:11
@@ -7,4 +7,4 @@
 local expl
 
 _wanted zsh-options expl 'set zsh option' \
-    compadd "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -a _set_options
+    compadd "$@" -M 'B:[nN][oO]= M:_= M:{A-Z}={a-z}' -a _set_options
Index: Completion/Core/_unset_options
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Core/_unset_options,v
retrieving revision 1.2
diff -u -r1.2 _unset_options
--- Completion/Core/_unset_options	2000/05/31 09:38:26	1.2
+++ Completion/Core/_unset_options	2000/06/19 10:39:11
@@ -7,4 +7,4 @@
 local expl
 
 _wanted zsh-options expl 'unset zsh option' \
-    compadd "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -a _unset_options
+    compadd "$@" -M 'B:[nN][oO]= M:_= M:{A-Z}={a-z}' -a _unset_options
Index: Doc/Zsh/compwid.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compwid.yo,v
retrieving revision 1.17
diff -u -r1.17 compwid.yo
--- Doc/Zsh/compwid.yo	2000/05/31 09:56:12	1.17
+++ Doc/Zsh/compwid.yo	2000/06/19 10:39:11
@@ -815,7 +815,9 @@
 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))(
+xitem(tt(L:)var(lanchor)tt(||)var(ranchor)tt(=)var(tpat))
+xitem(tt(b:)var(lpat)tt(=)var(tpat))
+item(tt(B:)var(lpat)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
@@ -828,14 +830,21 @@
 between substrings matched by var(lanchor) and var(ranchor). Unlike
 var(lanchor), the var(ranchor) only needs to match the trial
 completion string.
+
+The tt(b) and tt(B) forms are similar to tt(l) and tt(L) with an empty 
+anchor, but need to match only the beginning of the trial completion
+or the word on the command line, respectively.
 )
 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(ranchor) forces the match to the end of the command line string.
+xitem(tt(R:)var(lanchor)tt(||)var(ranchor)tt(=)var(tpat))
+xitem(tt(e:)var(lpat)tt(=)var(tpat))
+item(tt(E:)var(lpat)tt(=)var(tpat))(
+As tt(l), tt(L), tt(b) and tt(B), with the difference that the command
+line and trial completion patterns are anchored on the right side.
+Here an empty var(ranchor) and the tt(e) and tt(E) forms force the
+match to the end of the trial completion or command line string.
 )
 enditem()
 
@@ -897,6 +906,18 @@
 specification characters (tt(L) and tt(M)) guarantees that what has
 already been typed on the command line (in particular the prefix
 tt(no)) will not be deleted.
+
+Note that the use of tt(L) in the first part means that it matches
+only when at the beginning of both the command line string and the
+trial completion. I.e., the string `tt(_NO_f)' would not be
+completed to `tt(_NO_foo)', nor would `tt(NONO_f)' be completed to
+`tt(NONO_foo)' because of the leading underscore or the second
+`tt(NO)' on the line which makes the pattern fail even though they are 
+otherwise ignored. To fix this, one would use `tt(B:[nN][oO]=)'
+instead of the first part. As described above, this matches at the
+beginning of the trial completion, independent of other characters or
+substrings at the beginning of the command line word which are ignored
+by the same or other var(spec)s.
 
 The second example makes completion case insensitive.  This is just
 the same as in the option example, except here we wish to retain the
Index: Src/Zle/comp.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/comp.h,v
retrieving revision 1.6
diff -u -r1.6 comp.h
--- Src/Zle/comp.h	2000/05/23 14:23:27	1.6
+++ Src/Zle/comp.h	2000/06/19 10:39:12
@@ -150,6 +150,7 @@
 #define CMF_LINE  1
 #define CMF_LEFT  2
 #define CMF_RIGHT 4
+#define CMF_INTER 8
 
 struct cpattern {
     Cpattern next;		/* next sub-pattern */
Index: Src/Zle/complete.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/complete.c,v
retrieving revision 1.12
diff -u -r1.12 complete.c
--- Src/Zle/complete.c	2000/06/13 09:05:37	1.12
+++ Src/Zle/complete.c	2000/06/19 10:39:12
@@ -183,13 +183,13 @@
 {
     Cmatcher ret = NULL, r = NULL, n;
     Cpattern line, word, left, right;
-    int fl, ll, wl, lal, ral, err, both;
+    int fl, fl2, ll, wl, lal, ral, err, both;
 
     if (!*s)
 	return NULL;
 
     while (*s) {
-	lal = ral = both = 0;
+	lal = ral = both = fl2 = 0;
 	left = right = NULL;
 
 	while (*s && inblank(*s)) s++;
@@ -197,10 +197,14 @@
 	if (!*s) break;
 
 	switch (*s) {
+	case 'b': fl2 = CMF_INTER;
 	case 'l': fl = CMF_LEFT; break;
+	case 'e': fl2 = CMF_INTER;
 	case 'r': fl = CMF_RIGHT; break;
 	case 'm': fl = 0; break;
+	case 'B': fl2 = CMF_INTER;
 	case 'L': fl = CMF_LEFT | CMF_LINE; break;
+	case 'E': fl2 = CMF_INTER;
 	case 'R': fl = CMF_RIGHT | CMF_LINE; break;
 	case 'M': fl = CMF_LINE; break;
 	default:
@@ -220,7 +224,7 @@
 		zwarnnam(name, "missing patterns", NULL, 0);
 	    return pcm_err;
 	}
-	if (fl & CMF_LEFT) {
+	if ((fl & CMF_LEFT) && !fl2) {
 	    left = parse_pattern(name, &s, &lal, '|', &err);
 	    if (err)
 		return pcm_err;
@@ -236,7 +240,8 @@
 	} else
 	    left = NULL;
 
-	line = parse_pattern(name, &s, &ll, ((fl & CMF_RIGHT) ? '|' : '='),
+	line = parse_pattern(name, &s, &ll,
+			     (((fl & CMF_RIGHT) && !fl2) ? '|' : '='),
 			     &err);
 	if (err)
 	    return pcm_err;
@@ -246,10 +251,10 @@
 	    line = NULL;
 	    ll = 0;
 	}
-	if ((fl & CMF_RIGHT) && (!*s || !*++s)) {
+	if ((fl & CMF_RIGHT) && !fl2 && (!*s || !*++s)) {
 	    if (name)
 		zwarnnam(name, "missing right anchor", NULL, 0);
-	} else if (!(fl & CMF_RIGHT)) {
+	} else if (!(fl & CMF_RIGHT) || fl2) {
 	    if (!*s) {
 		if (name)
 		    zwarnnam(name, "missing word pattern", NULL, 0);
@@ -257,7 +262,7 @@
 	    }
 	    s++;
 	}
-	if (fl & CMF_RIGHT) {
+	if ((fl & CMF_RIGHT) && !fl2) {
 	    if (*s == '|') {
 		left = line;
 		lal = ll;
@@ -304,7 +309,7 @@
 
 	n = (Cmatcher) hcalloc(sizeof(*ret));
 	n->next = NULL;
-	n->flags = fl;
+	n->flags = fl | fl2;
 	n->line = line;
 	n->llen = ll;
 	n->word = word;
Index: Src/Zle/compmatch.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/compmatch.c,v
retrieving revision 1.21
diff -u -r1.21 compmatch.c
--- Src/Zle/compmatch.c	2000/06/16 07:52:05	1.21
+++ Src/Zle/compmatch.c	2000/06/19 10:39:13
@@ -565,7 +565,9 @@
 					      NULL, NULL)) ||
 			      !match_parts(l + aoff, w + aoff, alen, part))))
 				continue;
-		    } else if (!both || il || iw)
+		    } else if (!both || ((mp->flags & CMF_INTER) ?
+					 ((mp->flags & CMF_LINE) ? iw : il) :
+					 (il || iw)))
 			continue;
 
 		    /* Fine, now we call ourselves recursively to find the
@@ -734,7 +736,9 @@
 					       tw - mp->lalen - mp->ralen,
 					       NULL, NULL));
 			else
-			    t = (!sfx && !il && !iw);
+			    t = (!sfx && !((mp->flags & CMF_INTER) ?
+					   ((mp->flags & CMF_LINE) ? iw : il) :
+					   (il || iw)));
 		    }
 		    if (mp->flags & CMF_RIGHT) {
 			/* Try to match the right anchor, if any. */
@@ -753,7 +757,9 @@
 					       mp->ralen - mp->lalen,
 					       NULL, NULL));
 			else
-			    t = (sfx && !il && !iw);
+			    t = (sfx && !((mp->flags & CMF_INTER) ?
+					  ((mp->flags & CMF_LINE) ? iw : il) :
+					  (il || iw)));
 		    }
 		    /* Now try to match the line and word patterns. */
 		    if (!t ||
Index: Test/54compmatch.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/54compmatch.ztst,v
retrieving revision 1.3
diff -u -r1.3 54compmatch.ztst
--- Test/54compmatch.ztst	2000/06/15 09:10:23	1.3
+++ Test/54compmatch.ztst	2000/06/19 10:39:13
@@ -254,6 +254,18 @@
 >line: {tst ___list_beep__ }{}
 >COMPADD:{}
 
+ test_code 'B:[nN][oO]= M:_= M:{A-Z}={a-z}' example1_list
+ comptest $'tst __no_listbe\t'
+0:Documentation example for options, input "__no_listbe"
+>line: {tst __no_listbeep }{}
+>COMPADD:{}
+
+ test_code 'B:[nN][oO]= M:_= M:{A-Z}={a-z}' example1_list
+ comptest $'tst nonono_listbe\t'
+0:Documentation example for options, input "nonono_listbe"
+>line: {tst nonono_listbeep }{}
+>COMPADD:{}
+
  lower_insensitive_M="M:{a-z}={A-Z}"
  lower_insensitive_m="m:{a-z}={A-Z}"
  example2_list=(ABC Abc abc)

--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author