summaryrefslogtreecommitdiff
path: root/src/fs.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 09:45:38 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:16 -0300
commit157df8cb547ba4cf900b1f9eb75df15384985708 (patch)
tree248a415fe9431989e9468ef001a1dd364e249afe /src/fs.zig
parent2c03f710535a0b0aa143cd6c1fad04a45857a777 (diff)
downloadpardes-157df8cb547ba4cf900b1f9eb75df15384985708.tar.gz
pardes-157df8cb547ba4cf900b1f9eb75df15384985708.zip
A served-tree pane spoils no Grep, and `look .` from a gone directory is ENOENT
A pane named `/virtual` gave Grep the root `/`, which swallowed every other pane's directory and ran out of walk before any file: every Grep missed. Grep passes over panes of the served tree. And `.` from a pane whose directory was gone resolved to the served tree's root (/virtual/), or through the jump list to another pane's directory: a dot path is the looking pane's own, and gone it fails, `look: <dir>: no such directory`. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/fs.zig')
-rw-r--r--src/fs.zig12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/fs.zig b/src/fs.zig
index 352aa0c4..de02e8e8 100644
--- a/src/fs.zig
+++ b/src/fs.zig
@@ -677,7 +677,9 @@ pub fn resolve(p: ?*pardes.Pardes, word: []const u8, cwd: []const u8, out: *[409
if (std.mem.startsWith(u8, joined, "/virtual/")) return resolveVirtual(p, joined[8..], out);
if (resolveOs(joined, out)) |found| return found;
if (resolveVirtual(p, joined, out)) |found| return found;
- if (resolveVirtual(p, word, out)) |found| return found;
+ // `.`, `..` and `./x` name the pane's directory, never the served tree:
+ // with that directory gone they name nothing (`.` would be /virtual/).
+ if (!dotRelative(word)) if (resolveVirtual(p, word, out)) |found| return found;
if (resolveEmbedded(word, cwd, out)) |source| {
const path = std.fmt.bufPrint(out, "/virtual/{s}", .{source.path}) catch return null;
return .{ .path = path };
@@ -685,6 +687,14 @@ pub fn resolve(p: ?*pardes.Pardes, word: []const u8, cwd: []const u8, out: *[409
return null;
}
+/// Whether `word` is spelled relative to the directory it is looked from:
+/// `.`, `..`, `./x`, `../x`.
+pub fn dotRelative(word: []const u8) bool {
+ const w = std.mem.trimEnd(u8, word, "/");
+ return std.mem.eql(u8, w, ".") or std.mem.eql(u8, w, "..") or
+ std.mem.startsWith(u8, word, "./") or std.mem.startsWith(u8, word, "../");
+}
+
/// Where a path really is on the host, and whether it is a directory. The
/// path may lie in a mount this editor serves, so the turn is given up for
/// the syscalls: another thread answers them.