summaryrefslogtreecommitdiff
path: root/src/look.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-10-01 06:17:47 -0300
committerGabriel Schneider <[email protected]>2026-10-01 07:16:43 -0300
commitdf10c37122cc3e6565d13aeefb9466dc6c0dc780 (patch)
tree5d8492f59c5488f1c4c5abda514b79e5d34945ea /src/look.zig
parent94f0c9359dc1b8ccd73bf58812bec9e78fb52073 (diff)
downloadpardes-df10c37122cc3e6565d13aeefb9466dc6c0dc780.tar.gz
pardes-df10c37122cc3e6565d13aeefb9466dc6c0dc780.zip
Grep and Find pass over a directory they may not open and keep every other hit, saying in one line how many they skipped
One `chmod 000` directory anywhere under a pane made every Grep say `pattern not found` and every Find `access denied`: the walk's `try w.enter`/`try w.next` ended it at the first refusal. Each is now counted and passed over, and the +Search ends `N directories skipped: permission denied` under the hits. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/look.zig')
-rw-r--r--src/look.zig12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/look.zig b/src/look.zig
index f208c1fb..21148b37 100644
--- a/src/look.zig
+++ b/src/look.zig
@@ -593,6 +593,7 @@ pub fn runSearch(p: *Pardes, id: usize, pat_raw: []const u8, kind: Search, start
var out_len: usize = 0;
var nrows: usize = 0;
var anchor: ?usize = null;
+ var skipped: usize = 0;
if (kind == .grep) {
var roots: [MAX_PANES][]const u8 = undefined;
var nroots: usize = 0;
@@ -625,13 +626,13 @@ pub fn runSearch(p: *Pardes, id: usize, pat_raw: []const u8, kind: Search, start
// not made yet, a peer's) has nothing to grep: passed over, not the
// search's failure.
for (roots[0..nroots]) |r|
- out_len += filesystem.grep(arena, p.gpa, r, dir, pat, out[out_len..]) catch |err| switch (err) {
+ out_len += filesystem.grep(arena, p.gpa, r, dir, pat, out[out_len..], &skipped) catch |err| switch (err) {
error.FileNotFound, error.NotDir, error.AccessDenied => continue,
else => return err,
};
nrows = std.mem.count(u8, out[0..out_len], "\n");
} else if (kind == .find) {
- out_len = try filesystem.find(arena, dir, pat, out);
+ out_len = try filesystem.find(arena, dir, pat, out, &skipped);
nrows = std.mem.count(u8, out[0..out_len], "\n");
} else if (pane.hasPdf()) {
if (comptime pdf_enabled) {
@@ -672,6 +673,13 @@ pub fn runSearch(p: *Pardes, id: usize, pat_raw: []const u8, kind: Search, start
nrows += 1;
}
}
+ // What the walk could not open is said in one line under the hits, so
+ // a locked directory reads as passed over, not as nothing there.
+ if (skipped > 0) {
+ const note = std.fmt.bufPrint(out[out_len..], "{d} director{s} skipped: permission denied\n", .{ skipped, if (skipped == 1) "y" else "ies" }) catch "";
+ out_len += note.len;
+ nrows += @intFromBool(note.len > 0);
+ }
// A Find or Grep that finds nothing empties its directory's +Search, if
// there is one, rather than leave the last search's rows looking like
// this one's.