diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Output.zig | 17 | ||||
| -rw-r--r-- | src/fs.zig | 3 | ||||
| -rw-r--r-- | src/ninep/ctl.zig | 9 |
3 files changed, 26 insertions, 3 deletions
diff --git a/src/Output.zig b/src/Output.zig index b32a40a2..37d25168 100644 --- a/src/Output.zig +++ b/src/Output.zig @@ -406,6 +406,16 @@ pub fn open(p: *Pardes, id: usize, dir: []const u8, from: Origin, arg: []const u return pane; } +/// 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. +fn fileSearch(from: Origin) bool { + return switch (from) { + .cmd => |c| c == .Find or c == .Grep, + else => false, + }; +} + pub fn fillResults(p: *Pardes, id: usize, dir: []const u8, from: Origin, arg: []const u8, content: []u8, initial_anchor: ?usize) !void { var result_content = content; errdefer p.gpa.free(result_content); @@ -448,9 +458,12 @@ pub fn fillResults(p: *Pardes, id: usize, dir: []const u8, from: Origin, arg: [] const rp = slot orelse continue; const rf = if (rp.file) |*f| f else continue; const o = if (rf.output) |*x| x else continue; - if (!std.meta.eql(o.from, from)) continue; - if (by_arg and !std.mem.eql(u8, o.arg(), arg)) continue; + const shared = fileSearch(from) and fileSearch(o.from); + if (!shared and !std.meta.eql(o.from, from)) continue; + if (!shared and by_arg and !std.mem.eql(u8, o.arg(), arg)) continue; if (!std.mem.eql(u8, std.fs.path.dirname(rf.path) orelse "", dir)) continue; + o.from = from; + p.fs.refilled = rp.serial; try setArg(o, arg); if (std.mem.eql(u8, rf.content, result_content)) { p.gpa.free(result_content); @@ -1316,6 +1316,9 @@ pub const Namespace = struct { /// The serial of the pane the root's exec or look last ran a line at /// (the keyboard's), 0 before one: its err record names that pane. ran_at: u32 = 0, + /// The output pane a search just filled again rather than made + /// (Output.fillResults): what an exec reads back. + refilled: ?u32 = null, /// Every failure said (Messages.reportFailure), counted: a builtin /// that said one while it ran failed. failures: u32 = 0, diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index a474c781..fbda6113 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -73,6 +73,7 @@ pub fn run(p: *Pardes, id: usize, exec: bool, text: []const u8, in_tag: bool) vo // An exec answers the pane it went to: a command pane it reused, or // the terminal it typed into. p.look_missed = false; + p.fs.refilled = null; const went: ?usize = if (exec) pardes.exec.execute(p, id, text) else blk: { look.lookAt(p, id, text); break :blk null; @@ -88,6 +89,9 @@ pub fn run(p: *Pardes, id: usize, exec: bool, text: []const u8, in_tag: bool) vo created = true; }; if (created) return; + // A +Search it filled again (Find and Grep reuse one): that is what it + // touched. + if (p.fs.refilled) |serial| if (p.paneBySerial(serial) != null) return noteResult(p, serial); if (went) |dst| if (p.panes[dst]) |pane| return noteResult(p, pane.serial); noteResult(p, if (exec) context else (p.panes[p.active] orelse return).serial); } @@ -1841,7 +1845,8 @@ test "Grep with no hit says grep: no match and opens nothing, a missing pane dir const dir = dir_buf[0..try tmp.dir.realPath(testing.io, &dir_buf)]; var line: [4200]u8 = undefined; _ = wr(p, Node.of(serialOf(p), .name), try std.fmt.bufPrint(&line, "{s}/a.txt\n", .{dir})); - // A hit opens its +Search, a row a line: exec reads it back. + // A hit opens its +Search, a row a line: exec reads it back. Find and + // Grep share it, a directory's one +Search, each run replacing it. try testing.expectEqual(Status.ok, wr(p, Node.of(serialOf(p), .exec), "Grep bravo\n").reply.status); const grepped = p.panes[p.paneBySerial(try std.fmt.parseInt(u32, std.mem.trimEnd(u8, rd(p, root_exec, 0, 64).bytes, "\n"), 10)).?].?; try testing.expectEqual(@as(usize, 2), std.mem.count(u8, grepped.file.?.content, "other.txt:")); @@ -1850,6 +1855,8 @@ test "Grep with no hit says grep: no match and opens nothing, a missing pane dir try testing.expectEqual(Status.ok, wr(p, Node.of(serialOf(p), .exec), "Find other\n").reply.status); const found = p.panes[p.paneBySerial(try std.fmt.parseInt(u32, std.mem.trimEnd(u8, rd(p, root_exec, 0, 64).bytes, "\n"), 10)).?].?; try testing.expect(std.mem.indexOf(u8, found.file.?.content, "other.txt") != null); + try testing.expectEqual(grepped.serial, found.serial); + try testing.expect(std.mem.indexOf(u8, found.file.?.content, "bravo here") == null); // A second pane in a directory that is not there. const other = try th.newPane(p); _ = wr(p, Node.of(other, .name), "/tmp/pardes-no-such-dir-zz/b.txt\n"); |
