diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 09:45:38 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:16 -0300 |
| commit | 157df8cb547ba4cf900b1f9eb75df15384985708 (patch) | |
| tree | 248a415fe9431989e9468ef001a1dd364e249afe /src/fs.zig | |
| parent | 2c03f710535a0b0aa143cd6c1fad04a45857a777 (diff) | |
| download | pardes-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.zig | 12 |
1 files changed, 11 insertions, 1 deletions
@@ -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. |
