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