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

[PATCH] expand '..n' to equivalent number of '..' segments in fixdir



dian@lamia ~/work/zsh cd ..2
dian@lamia ~ cd ..123
dian@lamia / cd ~/..2/home/dian/work/../work/zsh
dian@lamia ~/work/zsh cd ..2/work/zsh
dian@lamia ~/work/zsh

I added a minimal test case and so far it seems to do what I expect, but I don't know if there are any side effects to worry about.

diff --git a/Src/builtin.c b/Src/builtin.c
index d5a874a95..3a13f19ee 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -1353,8 +1353,12 @@ fixdir(char *src)
 	    *dest = '\0';
 	    return chasedots;
 	}
-	if (src[0] == '.' && src[1] == '.' &&
-	    (src[2] == '\0' || src[2] == '/')) {
+	if (src[0] == '.' && src[1] == '.') {
+	    int backtracks = src[2] == '\0' || src[2] == '/' ? 1 : atoi(src + 2);
+
+	    if (backtracks < 1)
+		backtracks = 1;
+
 	    if (isset(CHASEDOTS) || chasedots > 1) {
 		chasedots = 1;
 		/* and treat as normal path segment */
@@ -1375,11 +1379,16 @@ fixdir(char *src)
 			*ptrd = '\0';
 			return 1;
 		    }
-		    for (dest--; dest > d0 + 1 && dest[-1] != '/'; dest--);
-		    if (dest[-1] != '/')
-			dest--;
+		    for (int i = 0; i < backtracks; i++) {
+			for (dest--; dest > d0 + 1 && dest[-1] != '/'; dest--);
+			if (dest[-1] != '/')
+			    dest--;
+			if (dest - 1 == d0)
+			    break;
+		    }
 		}
-		src++;
+		/* jump forward one space plus the length of any trailing digits */
+		src += backtracks == 1 ? 1 : (int) trunc(log10(backtracks)) + 2;
 		while (*++src == '/');
 		continue;
 	    }
diff --git a/Test/B01cd.ztst b/Test/B01cd.ztst
index 21e751dcb..f7f82147f 100644
--- a/Test/B01cd.ztst
+++ b/Test/B01cd.ztst
@@ -123,6 +123,14 @@ F:something is broken.  But you already knew that.
  print $PWD
 0q:Changing directory up through symbolic links without following them
 >$mydir
+>$mydir
+
+ cd $mydir/cdtst.tmp/sub/fake
+ cd ..3 &&
+ pwd &&
+ print $PWD
+0q:Changing directory up without following symlinks, shorter form
+>$mydir
 >$mydir
 
  setopt chaselinks



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