summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/fs.md3
-rw-r--r--src/Output.zig10
-rw-r--r--src/look.zig5
-rw-r--r--src/ninep/ctl.zig2
4 files changed, 18 insertions, 2 deletions
diff --git a/docs/fs.md b/docs/fs.md
index 1baa9b2c..6fa612f5 100644
--- a/docs/fs.md
+++ b/docs/fs.md
@@ -748,7 +748,8 @@ every pane's directory on this host, passing over panes of the served
tree (`/virtual/`, a peer's `/n/<name>/`) and directories not there,
so none of them spoils the rest; Find and Grep share one `+Search` a
directory, each run replacing what the last showed, as acme reuses a
-directory's `+Errors` (the exec reads that pane back), while a plain
+directory's `+Errors` (the exec reads that pane back; one that finds
+nothing empties it rather than leave the last rows), while a plain
word's `LookWord list` search keeps a pane a pattern, ENOSPC for no room or
slot, EBUSY for a held lock) -- and logs its reason exactly once, as `err <serial|->
<file>: <why>`, with no `msg` for it. A builtin a click runs (Save, get's
diff --git a/src/Output.zig b/src/Output.zig
index 99246b4a..eb9e8db4 100644
--- a/src/Output.zig
+++ b/src/Output.zig
@@ -418,6 +418,16 @@ pub fn open(p: *Pardes, id: usize, dir: []const u8, from: Origin, arg: []const u
/// Find and Grep share one +Search a directory, each run replacing what
/// the last showed, as acme reuses a directory's +Errors; a pane's own
/// search (LookWord list) keeps a pane a pattern.
+/// Whether `dir` has its Find/Grep +Search open.
+pub fn hasFileSearch(p: *Pardes, dir: []const u8) bool {
+ for (p.panes) |slot| {
+ const f = (slot orelse continue).file orelse continue;
+ const o = f.output orelse continue;
+ if (fileSearch(o.from) and std.mem.eql(u8, std.fs.path.dirname(f.path) orelse "", dir)) return true;
+ }
+ return false;
+}
+
fn fileSearch(from: Origin) bool {
return switch (from) {
.cmd => |c| c == .Find or c == .Grep,
diff --git a/src/look.zig b/src/look.zig
index 0baa9afc..f45fe583 100644
--- a/src/look.zig
+++ b/src/look.zig
@@ -667,7 +667,10 @@ pub fn runSearch(p: *Pardes, id: usize, pat_raw: []const u8, kind: Search, start
nrows += 1;
}
}
- if (!open_empty and nrows == 0) return 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;
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
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index 2dc3a51b..a78a9fcd 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -1886,6 +1886,8 @@ test "Grep with no hit says grep: no match and opens nothing, a missing pane dir
var after: usize = 0;
for (p.panes) |slot| after += @intFromBool(slot != null);
try testing.expectEqual(count, after);
+ // The +Search the miss would have filled is emptied, not left stale.
+ try testing.expectEqualStrings("", found.file.?.content);
}
test "Unmount of a name not mounted says no such mount, which a mount reads as ENOENT" {