summaryrefslogtreecommitdiff
path: root/src/look.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-10-01 08:15:56 -0300
committerGabriel Schneider <[email protected]>2026-10-01 08:53:11 -0300
commita274bd2c706fdfd3effa0ad88c5b4083c0dc0f33 (patch)
tree1242a9341c5692e58890706a65bc89f6ad2e3633 /src/look.zig
parent577108ec6a003db9504b8376f3d88c21ccaf0765 (diff)
downloadpardes-a274bd2c706fdfd3effa0ad88c5b4083c0dc0f33.tar.gz
pardes-a274bd2c706fdfd3effa0ad88c5b4083c0dc0f33.zip
Grep and Find say when a cap hid what they might have found: `cut at 512 hits`, `N files read only in part (first 256 KiB)`, `walk cut at N entries`; one that finds nothing leaves the +Search as it was
Grep reads 256 KiB of a file and stops at 512 hits, and its walk at 20000 files or 100000 entries; Find stops at 512 names. A cap hit was silent, so a match past one read as `pattern not found`. The walk now notes each cap it hit (fs.WalkNotes) and the +Search says it in a line under the hits, as it says directories skipped; a search that found nothing but hit a cap opens the +Search with those lines, not a miss. A Find or Grep that finds nothing and passed nothing over leaves the directory's +Search with the last search's rows, its failure saying so, where it used to empty it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/look.zig')
-rw-r--r--src/look.zig28
1 files changed, 14 insertions, 14 deletions
diff --git a/src/look.zig b/src/look.zig
index c77119c5..11c77760 100644
--- a/src/look.zig
+++ b/src/look.zig
@@ -593,7 +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;
+ var notes: filesystem.WalkNotes = .{};
if (kind == .grep) {
var roots: [MAX_PANES][]const u8 = undefined;
var nroots: usize = 0;
@@ -626,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..], &skipped) catch |err| switch (err) {
+ out_len += filesystem.grep(arena, p.gpa, r, dir, pat, out[out_len..], &notes) 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, &skipped);
+ out_len = try filesystem.find(arena, dir, pat, out, &notes);
nrows = std.mem.count(u8, out[0..out_len], "\n");
} else if (pane.hasPdf()) {
if (comptime pdf_enabled) {
@@ -673,17 +673,17 @@ 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.
- if (!open_empty and nrows == 0 and (kind == .text or !panes.Output.hasFileSearch(p, dir))) return 0;
+ // What the walk passed over -- a directory it might not open, a file
+ // read in part, a cap it stopped at -- is said in lines under the hits,
+ // so a search that found nothing where it did not look says so, never
+ // just "not found".
+ const noted = notes.write(out[out_len..]);
+ out_len += noted;
+ nrows += std.mem.count(u8, out[out_len - noted .. out_len], "\n");
+ // A Find or Grep that finds nothing leaves its directory's +Search as
+ // it was: the failure says why, and the last search's rows are still
+ // that search's (its tag names it).
+ if (!open_empty and nrows == 0) return 0;
const content = try p.gpa.dupe(u8, out[0..out_len]);
// the buffer records WHICH search filled it, pattern and all: Find and
// Grep are builtins (words you can execute), the bare `/` is a key