diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 11:09:17 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:16 -0300 |
| commit | 5db9e71ba32dd6f0a0292eaa341d1d8ba805483c (patch) | |
| tree | feaf11471f49fdba5122922a960889ea4cb4f549 /src/ninep/ctl.zig | |
| parent | 6b46d0797003585a99f8e5b99b3e8cff635ebebc (diff) | |
| download | pardes-5db9e71ba32dd6f0a0292eaa341d1d8ba805483c.tar.gz pardes-5db9e71ba32dd6f0a0292eaa341d1d8ba805483c.zip | |
A remembered place is clamped to the file as it is now, its selection's two ends kept
A Recent row or a jumplist entry for a line the file no longer has failed the look; now it opens at the last line. The selection's anchor is remembered too, so a reopen restores both ends where they fit, and Recent and Jumplist share the (closed) marker.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep/ctl.zig')
| -rw-r--r-- | src/ninep/ctl.zig | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 477a91fe..889ee7be 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -2141,8 +2141,8 @@ test "a closed file is found again: Recent and /recent list it closed, a look at const rows = p.panes[p.paneBySerial(try std.fmt.parseInt(u32, std.mem.trimEnd(u8, rd(p, root_exec, 0, 64).bytes, "\n"), 10)).?].?; const at = std.mem.indexOf(u8, rows.file.?.content, try std.fmt.bufPrint(&want, "{s}:3:", .{a})).?; const row = rows.file.?.content[at .. std.mem.indexOfScalarPos(u8, rows.file.?.content, at, '\n').?]; - try testing.expect(std.mem.endsWith(u8, row, " closed")); - try testing.expectEqual(Status.ok, wr(p, Node.of(rows.serial, .look), try std.fmt.bufPrint(&line, "{s}\n", .{row[0 .. row.len - " closed".len]})).reply.status); + try testing.expect(std.mem.endsWith(u8, row, " (closed)")); + try testing.expectEqual(Status.ok, wr(p, Node.of(rows.serial, .look), try std.fmt.bufPrint(&line, "{s}\n", .{row[0 .. row.len - " (closed)".len]})).reply.status); p.sync(); const back = p.panes[p.active].?; try testing.expectEqualStrings(a, back.file.?.path); @@ -2163,6 +2163,42 @@ test "a closed file is found again: Recent and /recent list it closed, a look at try testing.expectEqualStrings(a, p.panes[p.active].?.file.?.path); } +test "a remembered place is clamped to the file as it is now, its selection's two ends kept where they fit" { + const p = try withFile(testing.allocator, "x\n"); + defer p.deinit(); + var tmp = testing.tmpDir(.{}); + defer tmp.cleanup(); + try tmp.dir.writeFile(testing.io, .{ .sub_path = "c.txt", .data = "one\ntwo\nthree\nfour\nfive\n" }); + var dir_buf: [4096]u8 = undefined; + const dir = dir_buf[0..try tmp.dir.realPath(testing.io, &dir_buf)]; + var line: [4200]u8 = undefined; + _ = wr(p, root_look, try std.fmt.bufPrint(&line, "{s}/c.txt:2\n", .{dir})); + p.sync(); + const c = p.panes[p.active].?; + // A selection over lines 2 to 4, then closed. + @import("pane.zig").setDot(c, .{ .q0 = 4, .q1 = 19 }); + try testing.expect(c.body.vsel.active); + _ = wr(p, Node.of(c.serial, .ctl), "Del\n"); + p.sync(); + // The file shrinks to two lines while it is closed. + try tmp.dir.writeFile(testing.io, .{ .sub_path = "c.txt", .data = "one\ntwo\n" }); + _ = wr(p, root_exec, "Recent\n"); + const rows = p.panes[p.paneBySerial(try std.fmt.parseInt(u32, std.mem.trimEnd(u8, rd(p, root_exec, 0, 64).bytes, "\n"), 10)).?].?; + const at = std.mem.indexOf(u8, rows.file.?.content, "c.txt:").?; + const row = rows.file.?.content[at .. std.mem.indexOfScalarPos(u8, rows.file.?.content, at, '\n').?]; + // Both ends are in the row, a range. + try testing.expect(std.mem.indexOfScalar(u8, row, '-') != null); + var full: [4400]u8 = undefined; + const loc = try std.fmt.bufPrint(&full, "{s}/{s}\n", .{ dir, row[0 .. std.mem.indexOfScalar(u8, row, ' ').?] }); + // A look at it opens the file, never a miss, clamped to its last line. + try testing.expectEqual(Status.ok, wr(p, Node.of(rows.serial, .look), loc).reply.status); + p.sync(); + const back = p.panes[p.active].?; + try testing.expect(std.mem.endsWith(u8, back.file.?.path, "/c.txt")); + try testing.expect(back.body.cur_row <= 1); + try testing.expect(back.body.vsel.active); +} + test "size is monotonic: growing is never refused, and a size once taken is taken again" { const p = try Pardes.init(testing.allocator, .{ .tty_only = true, .cols = 160, .rows = 60 }); defer p.deinit(); |
