diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 03:31:23 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:15 -0300 |
| commit | 3e941015ebd2da88a296479f407e9bbf06287234 (patch) | |
| tree | 91178a9c4d3a05994cc2390cd7906b3b63e5be32 /src/dump.zig | |
| parent | 52d822eee271c53f072c94d3fc7f262e1659eff1 (diff) | |
| download | pardes-3e941015ebd2da88a296479f407e9bbf06287234.tar.gz pardes-3e941015ebd2da88a296479f407e9bbf06287234.zip | |
A pane restored with unsaved text is asked about before it is thrown away
Exit, Restore, Del and get warn only about a pane edited since it was
opened, which its saved hash says (set at its first edit). A pane a Dump
kept dirty came back with no hash, so a restored session quit at once
over it. Restoring one dirty now gives it a hash its text does not match.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/dump.zig')
| -rw-r--r-- | src/dump.zig | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/dump.zig b/src/dump.zig index 88a95994..54b77451 100644 --- a/src/dump.zig +++ b/src/dump.zig @@ -949,3 +949,37 @@ test "a restored pane keeps its dot, as acme's dump keeps a window's" { try std.testing.expectEqual(@as(u32, 4), dot.q0); try std.testing.expectEqual(@as(u32, 7), dot.q1); } + +test "a pane restored with unsaved text is asked about by Exit, Restore, Del and get" { + const gpa = std.testing.allocator; + const p = try Pardes.init(gpa, .{ .tty_only = true }); + defer p.deinit(); + const pane = try p.setTestFile("saved\n"); + _ = ctlfs.pane.spliceBody(p, pane, 0, 0, "unsaved ").?; + try std.testing.expect(pane.file.?.revision != pane.file.?.saved_revision); + try dumpState(p); + // Restore reads its dump before it warns: one it can read. + var tmp = std.testing.tmpDir(.{}); + defer tmp.cleanup(); + try tmp.dir.writeFile(std.testing.io, .{ .sub_path = "d.zon", .data = p.dump_out.? }); + var dir_buf: [4096]u8 = undefined; + const dir = dir_buf[0..try tmp.dir.realPath(std.testing.io, &dir_buf)]; + var restore_line: [4200]u8 = undefined; + for ([_][]const u8{ "Exit", "Restore", "Del", "get" }) |word| { + const restored = try initFromDump(gpa, .{ .tty_only = true }, p.dump_out.?); + defer restored.deinit(); + const id = for (restored.panes, 0..) |slot, i| { + if (slot) |candidate| if (candidate.file != null and candidate.file.?.output == null) break i; + } else return error.FileLost; + const th = @import("ninep/testing.zig"); + const node = if (std.mem.eql(u8, word, "Del") or std.mem.eql(u8, word, "get")) + ctlfs.Node.of(restored.panes[id].?.serial, .ctl) + else + @intFromEnum(ctlfs.TopFile.ctl); + const line = if (std.mem.eql(u8, word, "Restore")) try std.fmt.bufPrint(&restore_line, "Restore {s}/d.zon\n", .{dir}) else if (std.mem.eql(u8, word, "Exit")) "Exit\n" else if (std.mem.eql(u8, word, "Del")) "Del\n" else "get\n"; + const answer = th.wr(restored, node, line); + try std.testing.expectEqual(ctlfs.Status.err, answer.reply.status); + try std.testing.expect(std.mem.indexOf(u8, answer.reply.ename, "Modified") != null); + try std.testing.expect(!restored.quit and restored.panes[id] != null); + } +} |
