diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-30 19:28:12 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:17 -0300 |
| commit | 42b68e5ea63c32ff9359f2268ef0d8c08eaafff2 (patch) | |
| tree | cd7c87754f0753f6029f26d1138b91a81df29744 | |
| parent | 939c369aee270067d9f030e2b234d93bae549988 (diff) | |
| download | pardes-42b68e5ea63c32ff9359f2268ef0d8c08eaafff2.tar.gz pardes-42b68e5ea63c32ff9359f2268ef0d8c08eaafff2.zip | |
Jumplist fills its one +Jumps again, as Recent does, never opening a second
Each Jumplist opened another +Jumps below the asking pane, so a few
clicks stacked stale copies of the list. Recent's refill of its own
pane is now shared, and Jumplist uses it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | src/Output.zig | 14 | ||||
| -rw-r--r-- | src/ninep/ctl.zig | 17 |
2 files changed, 26 insertions, 5 deletions
diff --git a/src/Output.zig b/src/Output.zig index 47fcc7e4..06f2f1dc 100644 --- a/src/Output.zig +++ b/src/Output.zig @@ -606,8 +606,7 @@ pub fn openJumps(p: *Pardes, id: usize) !void { else try out.writer.print("{s}:{d}:{d} {s}\n", .{ loc, j.line, j.col, what[0..cut] }); } - const content = try out.toOwnedSlice(); - try openStepped(p, id, .{ .cmd = .Jumplist }, content); + try refillOrOpen(p, id, .{ .cmd = .Jumplist }, try out.toOwnedSlice()); } /// The recent list as rows: `<path>:<line>:<col> open|closed`, most recent @@ -699,12 +698,17 @@ pub fn openRecent(p: *Pardes, id: usize) !void { var out: std.Io.Writer.Allocating = .init(p.gpa); errdefer out.deinit(); try recentText(p, &out.writer, true); - const content = try out.toOwnedSlice(); + try refillOrOpen(p, id, .{ .cmd = .Recent }, try out.toOwnedSlice()); +} + +/// The one stepped output from `from`, filled again with `content` when it +/// is there (Recent, Jumplist), or opened when it is not. +fn refillOrOpen(p: *Pardes, id: usize, from: Origin, content: []u8) !void { for (p.panes, 0..) |slot, i| { const rp = slot orelse continue; const rf = if (rp.file) |*f| f else continue; const o = rf.output orelse continue; - if (!std.meta.eql(o.from, Origin{ .cmd = .Recent })) continue; + if (!std.meta.eql(o.from, from)) continue; File.setContent(p, rf, content); resetBody(p, rp); p.fs.refilled = rp.serial; @@ -715,7 +719,7 @@ pub fn openRecent(p: *Pardes, id: usize) !void { look.armLookWalk(p, i); return; } - try openStepped(p, id, .{ .cmd = .Recent }, content); + try openStepped(p, id, from, content); } pub fn openThemes(p: *Pardes, id: usize) !void { diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index bc27f72b..4fab699a 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -2989,6 +2989,23 @@ test "a column takes panes until their documented minimums fill it, not until no } } +test "Jumplist fills its one +Jumps again, as Recent does, never a second" { + const p = try withFile(testing.allocator, "x\n"); + defer p.deinit(); + const serial = serialOf(p); + var count: [2]usize = undefined; + for (&count) |*n| { + try testing.expectEqual(Status.ok, wr(p, Node.of(serial, .exec), "Jumplist\n").reply.status); + p.sync(); + n.* = 0; + for (p.panes) |slot| if (slot) |pane| if (pane.file) |f| if (f.output) |o| { + n.* += @intFromBool(std.meta.eql(o.from, panes.Output.Origin{ .cmd = .Jumplist })); + }; + } + try testing.expectEqual(@as(usize, 1), count[0]); + try testing.expectEqual(@as(usize, 1), count[1]); +} + test "a Jumplist entry is (closed) only while no pane has its file open" { const p = try withFile(testing.allocator, "x\n"); defer p.deinit(); |
