summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Zle/compcore.c18
-rw-r--r--Src/Zle/compmatch.c50
2 files changed, 44 insertions, 24 deletions
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 348054e86..32776dc83 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -2376,7 +2376,7 @@ addmatches(Cadata dat, char **argv)
 		    ms = dupstring(s);
 		else
 		    sl = strlen(ms = multiquote(s, 0));
-		lc = bld_parts(ms, sl, -1, NULL);
+		lc = bld_parts(ms, sl, -1, NULL, NULL);
 		isexact = 0;
 	    } else if (!(ms = comp_match(lpre, lsuf, s, cp, &lc,
 					 (!(dat->aflags & CAF_QUOTE) ?
@@ -2520,7 +2520,7 @@ add_match_data(int alt, char *str, char *orig, Cline line,
 	for (pp = NULL, p = line; p->next; pp = p, p = p->next);
 
 	if (psl) {
-	    s = bld_parts(psuf, psl, psl, &sl);
+	    s = bld_parts(psuf, psl, psl, &sl, NULL);
 
 	    if (sline) {
 		Cline sp;
@@ -2554,7 +2554,7 @@ add_match_data(int alt, char *str, char *orig, Cline line,
 	if (isl) {
 	    Cline tsl;
 
-	    s = bld_parts(isuf, isl, isl, &tsl);
+	    s = bld_parts(isuf, isl, isl, &tsl, NULL);
 
 	    if (sl)
 		sl->next = s;
@@ -2573,7 +2573,7 @@ add_match_data(int alt, char *str, char *orig, Cline line,
 	    sl = tsl;
 	}
 	if (qisl) {
-	    Cline qsl = bld_parts(dupstring(qisuf), qisl, qisl, NULL);
+	    Cline qsl = bld_parts(dupstring(qisuf), qisl, qisl, NULL, NULL);
 
 	    qsl->flags |= CLF_SUF;
 	    qsl->suffix = qsl->prefix;
@@ -2616,7 +2616,7 @@ add_match_data(int alt, char *str, char *orig, Cline line,
 	    if (pline)
 		for (p = cp_cline(pline, 1), lp = p; lp->next; lp = lp->next);
 	    else
-		p = bld_parts(ppre, ppl, ppl, &lp);
+		p = bld_parts(ppre, ppl, ppl, &lp, NULL);
 
 	    if (lp->prefix && !(line->flags & (CLF_SUF | CLF_MID)) &&
 		!lp->llen && !lp->wlen && !lp->olen) {
@@ -2644,19 +2644,19 @@ add_match_data(int alt, char *str, char *orig, Cline line,
 	    }
 	}
 	if (pl) {
-	    Cline lp, p = bld_parts(pre, pl, pl, &lp);
+	    Cline lp, p = bld_parts(pre, pl, pl, &lp, NULL);
 
 	    lp->next = line;
 	    line = p;
 	}
 	if (ipl) {
-	    Cline lp, p = bld_parts(ipre, ipl, ipl, &lp);
+	    Cline lp, p = bld_parts(ipre, ipl, ipl, &lp, NULL);
 
 	    lp->next = line;
 	    line = p;
 	}
 	if (qipl) {
-	    Cline lp, p = bld_parts(dupstring(qipre), qipl, qipl, &lp);
+	    Cline lp, p = bld_parts(dupstring(qipre), qipl, qipl, &lp, NULL);
 
 	    lp->next = line;
 	    line = p;
@@ -2676,7 +2676,7 @@ add_match_data(int alt, char *str, char *orig, Cline line,
 	    if (ppl)
 		memcpy(apre + qipl + ipl + pl, ppre, ppl);
 
-	    p = bld_parts(apre, palen, palen, &lp);
+	    p = bld_parts(apre, palen, palen, &lp, NULL);
 
 	    if (pline)
 		for (lp->next = cp_cline(pline, 1); lp->next; lp = lp->next);
diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c
index b08dcd2bc..6dff2243e 100644
--- a/Src/Zle/compmatch.c
+++ b/Src/Zle/compmatch.c
@@ -337,22 +337,26 @@ static void
 add_match_part(Cmatcher m, char *l, char *w, int wl,
 	       char *o, int ol, char *s, int sl, int osl, int sfx)
 {
-    Cline p, lp;
+    Cline p, lp, lprem;
 
     /* If the anchors are equal, we keep only one. */
 
     if (l && !strncmp(l, w, wl))
 	l = NULL;
 
-    /* Split the new part into parts and turn the last one into a
-     * `suffix' if we have a left anchor. */
+    /*
+     * Split the new part into parts and turn the last one into a
+     * `suffix' if we have a left anchor---don't do this if the last one
+     * came from a right anchor before the end of the part we're
+     * splitting.
+     */
 
-    p = bld_parts(s, sl, osl, &lp);
+    p = bld_parts(s, sl, osl, &lp, &lprem);
 
-    if (m && (m->flags & CMF_LEFT)) {
-	lp->flags |= CLF_SUF;
-	lp->suffix = lp->prefix;
-	lp->prefix = NULL;
+    if (lprem && m && (m->flags & CMF_LEFT)) {
+	lprem->flags |= CLF_SUF;
+	lprem->suffix = lprem->prefix;
+	lprem->prefix = NULL;
     }
     /* cline lists for suffixes are sorted from back to front, so we have
      * to revert the list we got. */
@@ -418,7 +422,7 @@ add_match_sub(Cmatcher m, char *l, int ll, char *w, int wl)
     if (wl || ll) {
 	Cline p, lp;
 
-	if ((p = n = bld_parts(w, wl, ll, &lp)) && n != lp) {
+	if ((p = n = bld_parts(w, wl, ll, &lp, NULL)) && n != lp) {
 	    for (; p->next != lp; p = p->next);
 
 	    if (matchsubs) {
@@ -1016,7 +1020,7 @@ comp_match(char *pfx, char *sfx, char *w, Patprog cp, Cline *clp, int qu,
 	 * cline list for these matches, too. */
 	w = dupstring(w);
 	wl = strlen(w);
-	*clp = bld_parts(w, wl, wl, NULL);
+	*clp = bld_parts(w, wl, wl, NULL, NULL);
 	*exact = 0;
     } else {
 	Cline pli, plil;
@@ -1074,7 +1078,7 @@ comp_match(char *pfx, char *sfx, char *w, Patprog cp, Cline *clp, int qu,
 	    add_match_str(NULL, NULL, wpfx, wpl, 1);
 
 	    mli = bld_parts(w + rpl, wl - rpl - rsl,
-			    (mpl - rpl) + (msl - rsl), &mlil);
+			    (mpl - rpl) + (msl - rsl), &mlil, NULL);
 	    mlil->flags |= CLF_MID;
 	    mlil->slen = msl - rsl;
 	    mlil->next = revert_cline(matchparts);
@@ -1161,11 +1165,19 @@ pattern_match(Cpattern p, char *s, Cpattern wp, char *ws)
 /* This splits the given string into a list of cline structs, separated
  * at those places where one of the anchors of an `*' pattern was found.
  * plen gives the number of characters on the line that matched this
- * string. In lp we return a pointer to the last cline struct we build. */
+ * string.
+ *
+ * In *lp, if lp is not NULL, we return a pointer to the last cline struct we
+ * build.
+ *
+ * In *lprem, if lprem is not NULL, we return a pointer to the last
+ * cline struct we build if it came from the remainder of the
+ * line rather than from a right anchor match, else NULL.
+ */
 
 /**/
 Cline
-bld_parts(char *str, int len, int plen, Cline *lp)
+bld_parts(char *str, int len, int plen, Cline *lp, Cline *lprem)
 {
     Cline ret = NULL, *q = &ret, n = NULL;
     Cmlist ms;
@@ -1224,9 +1236,17 @@ bld_parts(char *str, int len, int plen, Cline *lp)
 	if (llen > olen)
 	    llen = olen;
 	n->prefix = get_cline(NULL, llen, p, olen, NULL, 0, 0);
+	if (lprem)
+	    *lprem = n;
+    }
+    else if (!ret) {
+        *q = n =
+	    get_cline(NULL, 0, NULL, 0, NULL, 0, (plen <= 0 ? CLF_NEW : 0));
+	if (lprem)
+	    *lprem = n;
+    } else if (lprem) {
+	*lprem = NULL;
     }
-    else if (!ret)
-        *q = n = get_cline(NULL, 0, NULL, 0, NULL, 0, (plen <= 0 ? CLF_NEW : 0));
 
     n->next = NULL;