about summary refs log tree commit diff
path: root/Src/Zle
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle')
-rw-r--r--Src/Zle/complete.c22
-rw-r--r--Src/Zle/compmatch.c64
2 files changed, 62 insertions, 24 deletions
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 58cd8a216..2746f52d3 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -182,12 +182,15 @@ parse_cmatcher(char *name, char *s)
 {
     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 @@ parse_cmatcher(char *name, char *s)
 	    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 @@ parse_cmatcher(char *name, char *s)
 			     &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 @@ parse_cmatcher(char *name, char *s)
 	    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;
diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c
index 24f482669..3a6a849b9 100644
--- a/Src/Zle/compmatch.c
+++ b/Src/Zle/compmatch.c
@@ -57,11 +57,9 @@ cmp_cmatchers(Cmatcher a, Cmatcher b)
 	     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 @@ match_str(char *l, char *w, Brinfo *bpp, int bc, int *rwlp,
 		    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 @@ match_str(char *l, char *w, Brinfo *bpp, int bc, int *rwlp,
 			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 @@ match_str(char *l, char *w, Brinfo *bpp, int bc, int *rwlp,
 			 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 @@ match_str(char *l, char *w, Brinfo *bpp, int bc, int *rwlp,
 		    }
 		    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 @@ bld_parts(char *str, int len, int plen, Cline *lp)
 	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