about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Completion/Core/_path_files34
-rw-r--r--Src/Zle/compmatch.c40
3 files changed, 54 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 345216be8..0dc4e9548 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2000-05-15  Sven Wischnowsky  <wischnow@zsh.org>
+
+	* 11364: Completion/Core/_path_files, Src/Zle/compmatch.c: fix for
+ 	suffix-matching; better in-path completion in _path_files
+	
 2000-05-15  Peter Stephenson  <pws@cambridgesiliconradio.com>
 
 	* 11362: Doc/Zsh/manual.yo, Doc/Zsh/metafaq.yo, Doc/Zsh/seealso.yo:
diff --git a/Completion/Core/_path_files b/Completion/Core/_path_files
index 899d96649..8f9a90245 100644
--- a/Completion/Core/_path_files
+++ b/Completion/Core/_path_files
@@ -6,7 +6,7 @@
 local linepath realpath donepath prepath testpath exppath skips skipped
 local tmp1 tmp2 tmp3 tmp4 i orig eorig pre suf tpre tsuf opre osuf cpre
 local pats haspats ignore pfxsfx remt sopt gopt opt sdirs ignpar
-local nm=$compstate[nmatches] menu matcher mopts sort match
+local nm=$compstate[nmatches] menu matcher mopts sort match mid
 
 typeset -U prepaths exppaths
 
@@ -529,6 +529,7 @@ for prepath in "$prepaths[@]"; do
       cpre="${cpre}${tpre%%/*}/"
       tpre="${tpre#*/}"
     elif [[ "$tsuf" = */* ]]; then
+      mid="$testpath"
       cpre="${cpre}${tpre}/"
       tpre="${tsuf#*/}"
       tsuf=
@@ -539,17 +540,32 @@ for prepath in "$prepaths[@]"; do
   done
 
   if [[ -z "$tmp4" ]]; then
-    if [[ "$osuf" = */* ]]; then
-      PREFIX="${opre}${osuf}"
-      SUFFIX=
-    else
+    if [[ "$mid" = */ ]]; then
       PREFIX="${opre}"
       SUFFIX="${osuf}"
+
+      tmp4="${testpath#${mid}}"
+      tmp3="${mid%/*/}"
+      tmp2="${${mid%/}##*/}"
+      compquote tmp4 tmp3 tmp2 tmp1
+      for i in "$tmp1[@]"; do
+        compadd -Qf "$mopts[@]" -p "$linepath$tmp3/" -s "/$tmp4$i" \
+                -W "$prepath$realpath${mid%/*/}/" \
+	        "$pfxsfx[@]" -M "r:|/=* r:|=*" - "$tmp2"
+      done
+    else
+      if [[ "$osuf" = */* ]]; then
+        PREFIX="${opre}${osuf}"
+        SUFFIX=
+      else
+        PREFIX="${opre}"
+        SUFFIX="${osuf}"
+      fi
+      tmp4="$testpath"
+      compquote tmp4 tmp1
+      compadd -Qf "$mopts[@]" -p "$linepath$tmp4" -W "$prepath$realpath$testpath" \
+	      "$pfxsfx[@]" -M "r:|/=* r:|=*" - "$tmp1[@]"
     fi
-    tmp4="$testpath"
-    compquote tmp4 tmp1
-    compadd -Qf "$mopts[@]" -p "$linepath$tmp4" -W "$prepath$realpath$testpath" \
-	    "$pfxsfx[@]" -M "r:|/=* r:|=*" - "$tmp1[@]"
   fi
 done
 
diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c
index fe9dad41b..3a9ea6a40 100644
--- a/Src/Zle/compmatch.c
+++ b/Src/Zle/compmatch.c
@@ -482,9 +482,10 @@ match_str(char *l, char *w, Brinfo *bpp, int bc, int *rwlp,
 	 */
 
 	bslash = 0;
-	if (test && (l[ind] == w[ind] ||
-		     (bslash = (lw > 1 && w[ind] == '\\' &&
-				(ind ? (w[0] == l[0]) : (w[1] == l[0])))))) {
+	if (test && !sfx &&
+	    (l[ind] == w[ind] ||
+	     (bslash = (lw > 1 && w[ind] == '\\' &&
+			(ind ? (w[0] == l[0]) : (w[1] == l[0])))))) {
 	    /* No matcher could be used, but the strings have the same
 	     * character here, skip over it. */
 	    l += add; w += (bslash ? (add + add ) : add);
@@ -562,10 +563,8 @@ match_str(char *l, char *w, Brinfo *bpp, int bc, int *rwlp,
 
 		    /* Fine, now we call ourselves recursively to find the
 		     * string matched by the `*'. */
-		    if (sfx) {
-			savl = l[-(llen + zoff)];
+		    if (sfx && (savl = l[-(llen + zoff)]))
 			l[-(llen + zoff)] = '\0';
-		    }
 		    for (t = 0, tp = w, ct = 0, ict = lw - alen + 1;
 			 ict;
 			 tp += add, ct++, ict--) {
@@ -585,11 +584,12 @@ match_str(char *l, char *w, Brinfo *bpp, int bc, int *rwlp,
 				!match_parts(l + aoff , tp - moff, alen, part))
 				break;
 			    if (sfx) {
-				savw = tp[-zoff];
-				tp[-zoff] = '\0';
+				if ((savw = tp[-zoff]))
+				    tp[-zoff] = '\0';
 				t = match_str(l - ll, w - lw,
 					      NULL, 0, NULL, 1, 2, part);
-				tp[-zoff] = savw;
+				if (savw)
+				    tp[-zoff] = savw;
 			    } else
 				t = match_str(l + llen + moff, tp + moff,
 					      NULL, 0, NULL, 0, 1, part);
@@ -598,7 +598,7 @@ match_str(char *l, char *w, Brinfo *bpp, int bc, int *rwlp,
 			}
 		    }
 		    ict = ct;
-		    if (sfx)
+		    if (sfx && savl)
 			l[-(llen + zoff)] = savl;
 
 		    /* Have we found a position in w where the rest of l
@@ -794,9 +794,10 @@ match_str(char *l, char *w, Brinfo *bpp, int bc, int *rwlp,
 	/* Same code as at the beginning, used in top-level calls. */
 
 	bslash = 0;
-	if (!test && (l[ind] == w[ind] ||
-		      (bslash = (lw > 1 && w[ind] == '\\' &&
-				 (ind ? (w[0] == l[0]) : (w[1] == l[0])))))) {
+	if ((!test || sfx) &&
+	    (l[ind] == w[ind] ||
+	     (bslash = (lw > 1 && w[ind] == '\\' &&
+			(ind ? (w[0] == l[0]) : (w[1] == l[0])))))) {
 	    /* No matcher could be used, but the strings have the same
 	     * character here, skip over it. */
 	    l += add; w += (bslash ? (add + add ) : add);
@@ -811,6 +812,8 @@ match_str(char *l, char *w, Brinfo *bpp, int bc, int *rwlp,
 	    lm = NULL;
 	    he = 0;
 	} else {
+	    if (!lw)
+		break;
 	    /* No matcher and different characters: l does not match w. */
 	    if (test)
 		return 0;
@@ -873,10 +876,15 @@ match_parts(char *l, char *w, int n, int part)
     char lsav = l[n], wsav = w[n];
     int ret;
 
-    l[n] = w[n] = '\0';
+    if (lsav)
+	l[n] = '\0';
+    if (wsav)
+	w[n] = '\0';
     ret = match_str(l, w, NULL, 0, NULL, 0, 1, part);
-    l[n] = lsav;
-    w[n] = wsav;
+    if (lsav)
+	l[n] = lsav;
+    if (wsav)
+	w[n] = wsav;
 
     return ret;
 }