summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Output.zig9
-rw-r--r--src/ninep/ctl.zig32
2 files changed, 41 insertions, 0 deletions
diff --git a/src/Output.zig b/src/Output.zig
index fc300e8b..5422411f 100644
--- a/src/Output.zig
+++ b/src/Output.zig
@@ -363,6 +363,15 @@ fn sortResults(arena: std.mem.Allocator, from: Origin, content: []u8, anchor: ?u
}
if (content.len == 0) return anchor;
const path_only = std.meta.eql(from, Origin{ .cmd = .Find });
+ // A walk's notes (fs.WalkNotes) stay under the hits: only the rows
+ // above the first are sorted.
+ if (path_only) {
+ var off: usize = 0;
+ var it = std.mem.splitScalar(u8, content, '\n');
+ while (it.next()) |line| : (off += line.len + 1) if (@import("fs.zig").WalkNotes.isNote(line)) {
+ return if (off == 0) anchor else sortResults(arena, from, content[0..off], anchor);
+ };
+ }
const trailing_newline = content[content.len - 1] == '\n';
const body = content[0 .. content.len - @intFromBool(trailing_newline)];
var lines = std.mem.splitScalar(u8, body, '\n');
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index d4f36bea..3b3873e3 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -4262,3 +4262,35 @@ test "a Rename the server answered for this file alone, with other open files sa
p.lspResponse(p.lsp_wait.?.id, "util.zig:1:8 sum\nmain.zig: also says add, which the server did not rename\n");
try testing.expect(th.logHas(p, "Rename: previewed, not applied: the server renamed in this file only, and 1 other open file(s) say the name"));
}
+
+test "Find ends with what it skipped, and a Find or Grep that finds nothing leaves the +Search as it was" {
+ if (comptime !pardes.hosted) return;
+ const gpa = testing.allocator;
+ var tmp = testing.tmpDir(.{});
+ defer tmp.cleanup();
+ try tmp.dir.writeFile(testing.io, .{ .sub_path = "zz-needle.txt", .data = "needle\n" });
+ try tmp.dir.createDirPath(testing.io, "locked");
+ var dir_buf: [4096]u8 = undefined;
+ const dir = dir_buf[0..try tmp.dir.realPath(testing.io, &dir_buf)];
+ var locked_buf: [4200]u8 = undefined;
+ const locked = try std.fmt.bufPrintSentinel(&locked_buf, "{s}/locked", .{dir}, 0);
+ if (std.c.chmod(locked, 0) != 0) return;
+ defer _ = std.c.chmod(locked, 0o755);
+ var path_buf: [4200]u8 = undefined;
+ const path = try std.fmt.bufPrint(&path_buf, "{s}/zz-needle.txt", .{dir});
+ const p = try Pardes.init(gpa, .{ .file = path, .tty_only = true, .cols = 80, .rows = 30 });
+ defer p.deinit();
+ try testing.expect(p.executeBuiltinLine(0, "Find needle"));
+ const search = p.panes[p.panes[0].?.search_pane.?].?;
+ const listed = search.file.?.content;
+ try testing.expect(std.mem.endsWith(u8, listed, "1 directory skipped: permission denied\n"));
+ try testing.expect(std.mem.startsWith(u8, listed, "zz-needle.txt\n"));
+ // Nothing found where it looked, and nothing passed over: the miss is
+ // said, and the +Search keeps the last search's rows.
+ _ = std.c.chmod(locked, 0o755);
+ const before = try gpa.dupe(u8, listed);
+ defer gpa.free(before);
+ try testing.expect(p.executeBuiltinLine(0, "Find nosuchname"));
+ try testing.expectEqualStrings(before, search.file.?.content);
+ try testing.expect(th.logHas(p, "Find: name not found"));
+}