summaryrefslogtreecommitdiff
path: root/src/fs.zig
diff options
context:
space:
mode:
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.