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

PATCH: 3.1.5 - Misc. completion repairs



Sven's patch from zsh-workers/4283 to make optional the second string
in r[] and R[] extended compctl patterns.

PWS's patches from zsh-workers/4124 and zsh-workers/4128 for various
auto-remove-suffix problems.  You definitely want these; sorry they're
so mixed in with the next bit.

Sven patch from zsh-workers/4140 for starting menu completion following a
call to a compctl that uses -U.

Index: Doc/Zsh/compctl.yo
===================================================================
diff -u -r1.1.1.2 -r1.12
--- compctl.yo	1998/10/30 15:56:50	1.1.1.2
+++ compctl.yo	1998/10/30 17:52:39	1.12
@@ -355,7 +355,10 @@
 tt(-K) option) which can examine the word components passed to it
 (or via the tt(read) builtin's tt(-c) and tt(-l) flags) and
 use its own criteria to decide what matches.  If there is no
-completion, the original word is retained.
+completion, the original word is retained.  Since the produced 
+possible completions seldom seldom have interesting common prefixes
+and suffixes, menucompletion is started immediatly if tt(AUTO_MENU) is
+set and this flag is used.
 )
 item(tt(-y) var(func-or-var))(
 The list provided by var(func-or-var) is displayed instead of the list
@@ -498,7 +501,8 @@
 item(tt(r[)var(str1)tt(,)var(str2)tt(])...)(
 Matches if the cursor is after a word with prefix var(str1).  If there
 is also a word with prefix var(str2) on the command line it matches
-only if the cursor is before this word.
+only if the cursor is before this word. If the comma and var(str2) are
+omitted, it matches if the cursor is after a word with prefix var(str1).
 )
 item(tt(R[)var(str1)tt(,)var(str2)tt(])...)(
 Like tt(r) but using pattern matching instead.
Index: Src/Zle/compctl.c
===================================================================
diff -u -r1.1.1.1 -r1.7
--- compctl.c	1998/06/01 17:08:45	1.1.1.1
+++ compctl.c	1998/08/25 16:53:15	1.7
@@ -600,27 +600,34 @@
 		    c->u.s.s[l] = ztrdup(tt);
 		} else if (c->type == CCT_RANGESTR ||
 			   c->type == CCT_RANGEPAT) {
+		    int hc;
+
 		    /* -r[..,..] or -R[..,..]:  two strings expected */
-		    for (; *t && *t != '\201'; t++);
+		    for (; *t && *t != '\201' && *t != '\200'; t++);
 		    if (!*t) {
 			zwarnnam(name, "error in condition", NULL, 0);
 			freecompcond(m);
 			return 1;
 		    }
+		    hc = (*t == '\201');
 		    *t = '\0';
 		    c->u.l.a[l] = ztrdup(tt);
-		    tt = ++t;
-		    /* any more commas are text, not active */
-		    for (; *t && *t != '\200'; t++)
-			if (*t == '\201')
-			    *t = ',';
-		    if (!*t) {
-			zwarnnam(name, "error in condition", NULL, 0);
-			freecompcond(m);
-			return 1;
+		    if (hc) {
+			tt = ++t;
+			/* any more commas are text, not active */
+			for (; *t && *t != '\200'; t++)
+			    if (*t == '\201')
+				*t = ',';
+			if (!*t) {
+			    zwarnnam(name, "error in condition", NULL, 0);
+			    freecompcond(m);
+			    return 1;
+			}
+			*t = '\0';
+			c->u.l.b[l] = ztrdup(tt);
 		    }
-		    *t = '\0';
-		    c->u.l.b[l] = ztrdup(tt);
+		    else
+			c->u.l.b[l] = NULL;
 		} else {
 		    /* remaining patterns are number followed by string */
 		    for (; *t && *t != '\200' && *t != '\201'; t++);
Index: Src/Zle/zle_tricky.c
===================================================================
diff -u -r1.1.1.2 -r1.15
--- zle_tricky.c	1998/10/30 15:57:15	1.1.1.2
+++ zle_tricky.c	1998/10/30 17:52:48	1.15
@@ -1895,7 +1895,7 @@
 				}
 				zsfree(s);
 			    }
-			    if (t) {
+			    if (t && cc->u.l.b[i]) {
 				if (cc->type == CCT_RANGEPAT)
 				    tokenize(sc = dupstring(cc->u.l.b[i]));
 				for (j++; j < clwnum; j++) {
@@ -2246,7 +2246,7 @@
 {
     Compctl cc = NULL;
     int oloffs = offs, owe = we, owb = wb, ocs = cs, oll = ll, isf = 1;
-    int t, sf1, sf2, ooffs;
+    int t, sf1, sf2, ooffs, um = usemenu;
     char *p, *sd = NULL, *tt, *s1, *s2, *os = NULL;
     unsigned char *ol = NULL;
 
@@ -2266,6 +2266,7 @@
     if (unset(COMPLETEINWORD) && cs != we)
 	cs = we, offs = strlen(s);
 
+    usemenu = um;
     ispattern = haswhat = lastambig = 0;
     patcomp = filecomp = NULL;
     menucur = NULL;
@@ -2413,6 +2414,7 @@
 	*delit = 1;
 	*s = '\0';
 	offs = 0;
+	if (isset(AUTOMENU)) usemenu = 1;
     } else
 	*delit = 0;
 
@@ -3235,9 +3237,10 @@
 do_ambiguous(void)
 {
     int p = (usemenu || ispattern), atend = (cs == we);
-    int inv = 0;
+    int inv = 0, am = 0;
 
     menucmp = 0;
+    fixsuffix();
 
     /* If we have to insert the first match, call do_single().  This is *
      * how REC_EXACT takes effect.  We effectively turn the ambiguous   *
@@ -3270,12 +3273,19 @@
 	    inststrlen(firstm + strlen(firstm) - ae, 0, ae);
 	if(ab || (ae && !atend))
 	    inv = 1;
+
+	/* If REC_EXACT and AUTO_MENU are set and what we inserted is an   *
+	 * exact match, we want to start menu completion now. Otherwise    *
+	 * on the next call to completion the inserted string would be     *
+	 * taken as a match and no menu completion would be started.       */
+	if (isset(RECEXACT) && (atend ? ab : ab + ae) == shortl) am = 1;
+
 	/* If the LIST_AMBIGUOUS option (meaning roughly `show a list only *
 	 * if the completion is completely ambiguous') is set, and some    *
 	 * prefix was inserted, return now, bypassing the list-displaying  *
 	 * code.  On the way, invalidate the list and note that we don't   *
 	 * want to enter an AUTO_MENU imediately.                          */
-	if(isset(LISTAMBIGUOUS) && inv) {
+	if(isset(LISTAMBIGUOUS) && inv && !am) {
 	    invalidatelist();
 	    lastambig = 0;
 	    return;
@@ -3289,6 +3299,7 @@
 	showinglist = -2;
     if(inv)
 	invalidatelist();
+    if (am) lastambig = 1;
 }
 
 /* This is a stat that ignores backslashes in the filename.  The `ls' *
@@ -3332,7 +3343,8 @@
 	    menupos = wb;
 	} else
 	    menupos = cs;
-	menuwe = (cs == we) || isset(ALWAYSTOEND);
+	/* menuwe == 2 means don't add space if no other suffix */
+	menuwe = (cs == we) ? 1 : isset(ALWAYSTOEND) ? 2 : 0;
 	menuend = we;
     }
     /* If we are already in a menu-completion or if we have done a *
@@ -3422,7 +3434,8 @@
 			fsuf, psuf);
 	    }
 	    /* And do the stat. */
-	    if (!ztat(p, &buf, 0) && S_ISDIR(buf.st_mode)) {
+	    if (p[strlen(p)-1] != '/' && !ztat(p, &buf, 0) &&
+		S_ISDIR(buf.st_mode)) {
 		/* It is a directory, so add the slash. */
 		havesuff = 1;
 		inststrlen("/", 1, 1);
@@ -3451,7 +3464,7 @@
 	    if(menuwe && isset(AUTOPARAMKEYS))
 		suffixlen[','] = suffixlen['}'] = 1;
 	}
-    } else if(!menucmp && !havesuff) {
+    } else if(!menucmp && !havesuff && menuwe != 2) {
 	/* If we didn't add a suffix, add a space, unless we are *
 	 * doing menu completion.                                */
 	inststrlen(" ", 1, 1);

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com



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