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

Re: Completion of files with spaces in



I wrote:

> Yep. The patch below should fix this, but it still has one problem:
> braces are not re-inserted in the right place if there were characters
> that needed quoting before them. I don't see a simple enough solution
> for this now, I'll have to think about this some more.

The patch below fixes that. Again, it looks big (removing the extra
argument to inststrlen() again).

Bye
 Sven

diff -u oos/Zle/zle_tricky.c Src/Zle/zle_tricky.c
--- oos/Zle/zle_tricky.c	Mon Mar 29 10:27:58 1999
+++ Src/Zle/zle_tricky.c	Mon Mar 29 10:30:08 1999
@@ -61,7 +61,7 @@
 #endif
 
 
-#define inststr(X) inststrlen((X),1,-1,0)
+#define inststr(X) inststrlen((X),1,-1)
 
 /* wb and we hold the beginning/end position of the word we are completing. */
 
@@ -105,12 +105,12 @@
 
 /* This is for completion inside a brace expansion. brbeg and brend hold  *
  * strings that were temporarily removed from the string to complete.     *
- * brpl and brsl, brbsl hold the offset of these strings.                 *
+ * brpl and brsl, hold the offset of these strings.                 *
  * brpcs and brscs hold the positions of the re-inserted string in the    *
  * line.                                                                  */
 
 static char *brbeg = NULL, *brend = NULL;
-static int brpl, brsl, brbsl, brpcs, brscs;
+static int brpl, brsl, brpcs, brscs, qbrpl, qbrsl, hasunqu;
 
 /* The list of matches.  fmatches contains the matches we first ignore *
  * because of fignore.                                                 */
@@ -161,6 +161,7 @@
 static char *fpre, *fsuf;
 static char *ipre, *ripre;
 static char *isuf;
+static char *qfpre, *qfsuf, *qrpre, *qrsuf, *qlpre, *qlsuf;
 static int lpl, lsl, rpl, rsl, fpl, fsl, lppl, lpsl;
 static int noreal;
 
@@ -515,7 +516,7 @@
 	cs = menupos + menulen + menuinsc;
 	iremovesuffix(' ', 1);
 
-	inststrlen(" ", 1, 1, 0);
+	inststrlen(" ", 1, 1);
 	menuinsc = menulen = 0;
 	menupos = cs;
 	menuwe = 1;
@@ -1506,11 +1507,13 @@
 
 	    if (tt && tt < s + myoffs) {
 		/* Braces are go:  delete opening brace */
-		char *com = NULL;
+		char *com = NULL, *tmp;
 		int pl, sl;
 
 		brbeg = dupstring(tt);
 		brpl = tt - s;
+		tmp = dupstrpfx(s, tt - s);
+		qbrpl = strlen(quotename(tmp, NULL));
 		pl = 1;
 		sl = 0;
 		chuck(tt);
@@ -1543,8 +1546,8 @@
 		    if (*p == Outbrace)
 			chuck(p);
 		    brsl = strlen(s) - (p - s);
-		    brbsl = p - s;
 		    brend[sl] = '\0';
+		    qbrsl = strlen(quotename(p, NULL));
 		}
 		/* we are still waiting for an outbrace and maybe commas */
 		if (brbeg)
@@ -2052,7 +2055,7 @@
 match_str(char *l, char *w, int *bp, int *rwlp, int sfx, int test)
 {
     int ll = strlen(l), lw = strlen(w), oll = ll, olw = lw;
-    int il = 0, iw = 0, t, ind, add, bc;
+    int il = 0, iw = 0, t, ind, add, bc = (bp ? *bp : 0);
     VARARR(unsigned char, ea, ll + 1);
     char *ow;
     Cmlist ms;
@@ -2066,9 +2069,9 @@
 
     if (sfx) {
 	l += ll; w += lw;
-	ind = -1; add = -1; bc = brsl;
+	ind = -1; add = -1;
     } else {
-	ind = 0; add = 1; bc = brpl;
+	ind = 0; add = 1;
     }
     /* ow will always point to the beginning (or end) of that sub-string
      * in w that wasn't put in the match-variables yet. */
@@ -2418,14 +2421,19 @@
 	wl = strlen(w);
 	*clp = bld_parts(w, wl, wl, NULL);
 	*exact = 0;
+	*bpl = (qu ? qbrpl : brpl);
+	*bsl = (qu ? qbrsl : brsl);
     } else {
 	Cline pli, plil;
 	int mpl, rpl, wl;
 
+	w = (qu ? quotename(w, NULL) : dupstring(w));
+
 	wl = strlen(w);
 
 	/* Always try to match the prefix. */
 
+	*bpl = (qu ? qbrpl : brpl);
 	if ((mpl = match_str(pfx, w, bpl, &rpl, 0, 0)) < 0)
 	    return NULL;
 
@@ -2450,6 +2458,7 @@
 	    plil = matchlastpart;
 
 	    /* The try to match the suffix. */
+	    *bsl = (qu ? qbrsl : brsl);
 	    if ((msl = match_str(sfx, w + mpl, bsl, &rsl, 1, 0)) < 0) {
 		free_cline(pli);
 
@@ -2488,8 +2497,6 @@
 	    pli = matchparts;
 	}
 	r = dupstring(matchbuf);
-	if (qu)
-	    r = quotename(r, NULL);
 
 	*clp = pli;
 
@@ -2501,6 +2508,9 @@
 	} else
 	    *exact = !strcmp(pfx, w);
     }
+    if (!qu)
+	hasunqu = 1;
+
     return r;
 }
 
@@ -3560,9 +3570,17 @@
 		    rems = NULL;
 		} else if (rems)
 		    rems = dupstring(rems);
+
+		/* Probably quote the prefix and suffix for testing. */
+		if (!cp && !(aflags & CAF_QUOTE)) {
+		    lpre = quotename(lpre, NULL);
+		    lsuf = quotename(lsuf, NULL);
+		    llpl = strlen(lpre);
+		    llsl = strlen(lsuf);
+		}
 	    }
 	    /* Walk through the matches given. */
-	    for (; (s = dupstring(*argv)); argv++) {
+	    for (; (s = *argv); argv++) {
 		sl = strlen(s);
 		bpl = brpl;
 		bsl = brsl;
@@ -3579,16 +3597,16 @@
 			    isalt = 1;
 		}
 		if (!(aflags & CAF_MATCH)) {
-		    ms = s;
-		    lc = bld_parts(s, sl, -1, NULL);
+		    ms = dupstring(s);
+		    lc = bld_parts(ms, sl, -1, NULL);
 		    isexact = 0;
 		} else if (!(ms = comp_match(lpre, lsuf, s, cp, &lc,
 					     !(aflags & CAF_QUOTE),
 					     &bpl, &bsl, &isexact)))
 		    continue;
 
-		cm = add_match_data(isalt, ms, lc, ipre, ipre, isuf, pre, prpre,
-				    ppre, psuf, suf, bpl, bsl,
+		cm = add_match_data(isalt, ms, lc, ipre, ipre, isuf, pre, 
+				    prpre, ppre, psuf, suf, bpl, bsl,
 				    flags, isexact);
 		cm->rems = rems;
 		cm->remf = remf;
@@ -3641,9 +3659,6 @@
     hn = (HashNode) t;
     pm = (Param) t;
 
-    if (incompfunc)
-	s = dupstring(s);
-
     if (addwhat == -1 || addwhat == -5 || addwhat == -6 ||
 	addwhat == CC_FILES || addwhat == -7 || addwhat == -8) {
 	if ((addwhat == CC_FILES ||
@@ -3657,10 +3672,13 @@
 		    !strcmp(*pt, s + sl - filell))
 		    isalt = 1;
 	}
-	if (!(ms = comp_match(fpre, fsuf, s, filecomp, &lc,
-			      (addwhat == CC_FILES || addwhat == -6 ||
-			       addwhat == -5 || addwhat == -8),
-			      &bpl, &bsl, &isexact)))
+	ms = ((addwhat == CC_FILES || addwhat == -6 ||
+	       addwhat == -5 || addwhat == -8) ? 
+	      comp_match(qfpre, qfsuf, s, filecomp, &lc, 1,
+			 &bpl, &bsl, &isexact) :
+	      comp_match(fpre, fsuf, s, filecomp, &lc, 0,
+			 &bpl, &bsl, &isexact));
+	if (!ms)
 	    return;
 
 	if (addwhat == -7 && !findcmd(s, 0))
@@ -3690,10 +3708,19 @@
 		 (((addwhat & CC_DISCMDS) && (hn->flags & DISABLED)) ||
 		  ((addwhat & CC_EXCMDS)  && !(hn->flags & DISABLED)))) ||
 		((addwhat & CC_BINDINGS) && !(hn->flags & DISABLED))))) {
-	if (!(ms = comp_match(rpre, rsuf, s, patcomp, &lc,
+	char *p1, *s1, *p2, *s2;
+
+	if (addwhat == CC_QUOTEFLAG) {
+	    p1 = qrpre; s1 = qrsuf;
+	    p2 = rpre;  s2 = rsuf;
+	} else {
+	    p1 = qlpre; s1 = qlsuf;
+	    p2 = lpre;  s2 = lsuf;
+	}
+	if (!(ms = comp_match(p1, s1, s, patcomp, &lc,
 			      (addwhat == CC_QUOTEFLAG),
 			      &bpl, &bsl, &isexact)) &&
-	    !(ms = comp_match(lpre, lsuf, s, NULL, &lc,
+	    !(ms = comp_match(p2, s2, s, NULL, &lc,
 			      (addwhat == CC_QUOTEFLAG),
 			      &bpl, &bsl, &isexact)))
 	    return;
@@ -4014,6 +4041,7 @@
 	ainfo = fainfo = NULL;
 	matchers = newlinklist();
 
+	hasunqu = 0;
 	useline = (lst != COMP_LIST_COMPLETE);
 	useexact = (isset(RECEXACT) && usemenu != 1);
 	uselist = (useline ?
@@ -5027,8 +5055,9 @@
     usemenu = um;
     patcomp = filecomp = NULL;
     menucur = NULL;
-    rpre = rsuf = lpre = lsuf = ppre = psuf = lppre = lpsuf = prpre =
-	fpre = fsuf = ipre = ripre = prpre = NULL;
+    rpre = rsuf = lpre = lsuf = ppre = psuf = lppre = lpsuf =
+	fpre = fsuf = ipre = ripre = prpre = 
+	qfpre = qfsuf = qrpre = qrsuf = qlpre = qlsuf = NULL;
 
     curcc = cc;
 
@@ -5136,8 +5165,10 @@
     lpre = zhalloc(lpl + 1);
     memcpy(lpre, s, lpl);
     lpre[lpl] = '\0';
+    qlpre = quotename(lpre, NULL);
     lsuf = dupstring(s + offs);
     lsl = strlen(lsuf);
+    qlsuf = quotename(lsuf, NULL);
 
     /* First check for ~.../... */
     if (ic == Tilde) {
@@ -5156,9 +5187,11 @@
     rpre = (*p || *lpre == Tilde || *lpre == Equals) ?
 	(noreal = 0, getreal(tt)) :
 	dupstring(tt);
+    qrpre = quotename(rpre, NULL);
 
     for (p = lsuf; *p && *p != String && *p != Tick; p++);
     rsuf = *p ? (noreal = 0, getreal(lsuf)) : dupstring(lsuf);
+    qrsuf = quotename(rsuf, NULL);
 
     /* Check if word is a pattern. */
 
@@ -5234,7 +5267,7 @@
 	    lppre = dupstring((char *) (line + wb));
 	    line[cs] = save;
 	    if (brbeg && *brbeg)
-		strcpy(lppre + brpl, lppre + brpl + strlen(brbeg));
+		strcpy(lppre + qbrpl, lppre + qbrpl + strlen(brbeg));
 	    if ((p = strrchr(lppre, '/'))) {
 		p[1] = '\0';
 		lppl = strlen(lppre);
@@ -5256,7 +5289,7 @@
 	    lpsuf = dupstring((char *) (line + cs));
 	    line[we] = save;
 	    if (brend && *brend) {
-		char *p = lpsuf + brsl - (cs - wb);
+		char *p = lpsuf + qbrsl - (cs - wb);
 
 		strcpy(p, p + strlen(brend));
 	    }
@@ -5271,8 +5304,10 @@
 	/* And get the file prefix. */
 	fpre = dupstring(((s1 == s || s1 == rpre || ic) &&
 			  (*s != '/' || cs == wb)) ? s1 : s1 + 1);
+	qfpre = quotename(fpre, NULL);
 	/* And the suffix. */
 	fsuf = dupstrpfx(rsuf, s2 - rsuf);
+	qfsuf = quotename(fsuf, NULL);
 
 	if (comppatmatch && *comppatmatch && (ispattern & 2)) {
 	    int t2;
@@ -5536,6 +5571,7 @@
 	 * that things starting with these characters will be added.   */
 	rpre = dyncat((ic == Tilde) ? "~" : "=", rpre);
 	rpl++;
+	qrpre = dyncat((ic == Tilde) ? "~" : "=", qrpre);
     }
     if (!ic && (cc->mask & CC_COMMPATH) && !*ppre && !*psuf) {
 	/* If we have to complete commands, add alias names, *
@@ -6320,19 +6356,12 @@
 
 /**/
 static int
-inststrlen(char *str, int move, int len, int qu)
+inststrlen(char *str, int move, int len)
 {
     if (!len || !str)
 	return 0;
     if (len == -1)
 	len = strlen(str);
-    if (qu) {
-	VARARR(char, b,  len + 1);
-	memcpy(b, str, len);
-	b[len] = '\0';
-	str = quotename(b, NULL);
-	len = strlen(str);
-    }
     spaceinline(len);
     strncpy((char *)(line + cs), str, len);
     if (move)
@@ -6358,17 +6387,18 @@
      * to re-insert. */
     if (ins) {
 	if ((hasp = (brbeg && *brbeg))) {
-	    plen = strlen(brbeg); pl = brpl;
+	    plen = strlen(brbeg); pl = (hasunqu ? brpl : qbrpl);
 	}
 	if ((hass = (brend && *brend))) {
-	    slen = strlen(brend); sl = we - wb - brsl - plen - slen + 1;
+	    slen = strlen(brend);
+	    sl = we - wb - (hasunqu ? brsl : qbrsl) - plen - slen + 1;
 	}
 	if (!pl) {
-	    inststrlen(brbeg, 1, -1, 0);
+	    inststrlen(brbeg, 1, -1);
 	    pl = -1; hasp = 0;
 	}
 	if (!sl) {
-	    inststrlen(brend, 1, -1, 0);
+	    inststrlen(brend, 1, -1);
 	    sl = -1; hass = 0;
 	}
     }
@@ -6380,7 +6410,7 @@
 	    spos = -1;
 	/* Insert the original string if no prefix. */
 	if (l->olen && !(l->flags & CLF_SUF) && !l->prefix) {
-	    inststrlen(l->orig, 1, l->olen, 1);
+	    inststrlen(l->orig, 1, l->olen);
 	    if (ins) {
 		li += l->olen;
 		if (pl >= 0 && li >= pl) {
@@ -6395,9 +6425,9 @@
 	    for (s = l->prefix; s; s = s->next) {
 		pcs = cs;
 		if (s->flags & CLF_LINE)
-		    inststrlen(s->line, 1, s->llen, 1);
+		    inststrlen(s->line, 1, s->llen);
 		else
-		    inststrlen(s->word, 1, s->wlen, 1);
+		    inststrlen(s->word, 1, s->wlen);
 		if (d < 0 && (s->flags & CLF_DIFF))
 		    d = cs;
 		if (ins) {
@@ -6418,9 +6448,9 @@
 	pcs = cs;
 	/* Insert the anchor. */
 	if (l->flags & CLF_LINE)
-	    inststrlen(l->line, 1, l->llen, 1);
+	    inststrlen(l->line, 1, l->llen);
 	else
-	    inststrlen(l->word, 1, l->wlen, 1);
+	    inststrlen(l->word, 1, l->wlen);
 	if (ins) {
 	    li += l->llen;
 	    if (pl >= 0 && li >= pl) {
@@ -6440,7 +6470,7 @@
 	/* And now insert the suffix or the original string. */
 	if (l->olen && (l->flags & CLF_SUF) && !l->suffix) {
 	    pcs = cs;
-	    inststrlen(l->orig, 1, l->olen, 1);
+	    inststrlen(l->orig, 1, l->olen);
 	    if (ins) {
 		li += l->olen;
 		if (pl >= 0 && li >= pl) {
@@ -6457,10 +6487,10 @@
 		if (j < 0 && (s->flags & CLF_DIFF))
 		    j = i;
 		if (s->flags & CLF_LINE) {
-		    inststrlen(s->line, 0, s->llen, 1);
+		    inststrlen(s->line, 0, s->llen);
 		    i += s->llen; pcs = cs + s->llen;
 		} else {
-		    inststrlen(s->word, 0, s->wlen, 1);
+		    inststrlen(s->word, 0, s->wlen);
 		    i += s->wlen; pcs = cs + s->wlen;
 		}
 		if (ins) {
@@ -6486,14 +6516,14 @@
 	    if (hasp && ppos >= 0) {
 		i = cs;
 		cs = ppos;
-		inststrlen(brbeg, 1, plen, 0);
+		inststrlen(brbeg, 1, plen);
 		cs = i + plen;
 		hasp = 0;
 	    }
 	    if (hass && spos >= 0) {
 		i = cs;
 		cs = spos;
-		inststrlen(brend, 1, slen, 0);
+		inststrlen(brend, 1, slen);
 		cs = i + slen;
 		hass = 0;
 	    }
@@ -6501,9 +6531,9 @@
 	l = l->next;
     }
     if (pl >= 0)
-	inststrlen(brbeg, 1, plen, 0);
+	inststrlen(brbeg, 1, plen);
     if (sl >= 0)
-	inststrlen(brend, 1, slen, 0);
+	inststrlen(brend, 1, slen);
 
     /* This calculates the new cursor position. If we had a mid cline
      * with missing characters, we take this, otherwise if we have a
@@ -6574,21 +6604,21 @@
 
     /* Ignored prefix. */
     if (m->ipre) {
-	inststrlen(m->ipre, 1, (l = strlen(m->ipre)), 0);
+	inststrlen(m->ipre, 1, (l = strlen(m->ipre)));
 	r += l;
     }
     /* -P prefix. */
     if (m->pre) {
-	inststrlen(m->pre, 1, (l = strlen(m->pre)), 0);
+	inststrlen(m->pre, 1, (l = strlen(m->pre)));
 	r += l;
     }
     /* Path prefix. */
     if (m->ppre) {
-	inststrlen(m->ppre, 1, (l = strlen(m->ppre)), 0);
+	inststrlen(m->ppre, 1, (l = strlen(m->ppre)));
 	r += l;
     }
     /* The string itself. */
-    inststrlen(m->str, 1, (l = strlen(m->str)), 0);
+    inststrlen(m->str, 1, (l = strlen(m->str)));
     r += l;
     ocs = cs;
     /* Re-insert the brace beginning, if any. */
@@ -6596,14 +6626,14 @@
 	cs = a + m->brpl + (m->pre ? strlen(m->pre) : 0);
 	l = strlen(brbeg);
 	brpcs = cs;
-	inststrlen(brbeg, 1, l, 0);
+	inststrlen(brbeg, 1, l);
 	r += l;
 	ocs += l;
 	cs = ocs;
     }
     /* Path suffix. */
     if (m->psuf) {
-	inststrlen(m->psuf, 1, (l = strlen(m->psuf)), 0);
+	inststrlen(m->psuf, 1, (l = strlen(m->psuf)));
 	r += l;
     }
     /* Re-insert the brace end. */
@@ -6612,19 +6642,19 @@
 	cs -= m->brsl;
 	ocs = brscs = cs;
 	l = strlen(brend);
-	inststrlen(brend, 1, l, 0);
+	inststrlen(brend, 1, l);
 	r += l;
 	cs = a + l;
     } else
 	brscs = -1;
     /* -S suffix */
     if (m->suf) {
-	inststrlen(m->suf, 1, (l = strlen(m->suf)), 0);
+	inststrlen(m->suf, 1, (l = strlen(m->suf)));
 	r += l;
     }
     /* ignored suffix */
     if (m->isuf) {
-	inststrlen(m->isuf, 1, (l = strlen(m->isuf)), 0);
+	inststrlen(m->isuf, 1, (l = strlen(m->isuf)));
 	r += l;
     }
     lastend = cs;
@@ -6802,7 +6832,7 @@
 	if (m->ripre && (m->flags & CMF_PARBR)) {
 	    /*{{*/
 	    /* Completing a parameter in braces.  Add a removable `}' suffix. */
-	    inststrlen("}", 1, 1, 0);
+	    inststrlen("}", 1, 1);
 	    menuinsc++;
 	    if (menuwe)
 		menuend++;
@@ -6823,7 +6853,7 @@
 	    if (!(sr = ztat(p, &buf, 0)) && S_ISDIR(buf.st_mode)) {
 		/* It is a directory, so add the slash. */
 		havesuff = 1;
-		inststrlen("/", 1, 1, 0);
+		inststrlen("/", 1, 1);
 		menuinsc++;
 		if (menuwe)
 		    menuend++;
@@ -6847,7 +6877,7 @@
 	    /* Otherwise, add a `,' suffix, and let `}' remove it. */
 	    cs = menuend;
 	    havesuff = 1;
-	    inststrlen(",", 1, 1, 0);
+	    inststrlen(",", 1, 1);
 	    menuinsc++;
 	    makesuffix(1);
 	    if ((!menucmp || menuwe) && isset(AUTOPARAMKEYS))
@@ -6857,7 +6887,7 @@
 	/* If we didn't add a suffix, add a space, unless we are *
 	 * doing menu completion or we are completing files and  *
 	 * the string doesn't name an existing file.             */
-	inststrlen(" ", 1, 1, 0);
+	inststrlen(" ", 1, 1);
 	menuinsc++;
 	if (menuwe)
 	    makesuffix(1);

--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



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