diff options
| author | Gabriel Schneider <[email protected]> | 2026-10-01 08:15:56 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 08:53:11 -0300 |
| commit | a274bd2c706fdfd3effa0ad88c5b4083c0dc0f33 (patch) | |
| tree | 1242a9341c5692e58890706a65bc89f6ad2e3633 /src/look.zig | |
| parent | 577108ec6a003db9504b8376f3d88c21ccaf0765 (diff) | |
| download | pardes-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.zig | 28 |
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..], ¬es) 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, ¬es); 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 |
