diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 04:18:04 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:15 -0300 |
| commit | 35e72930c11af5563da9d62df2b74a7439f36653 (patch) | |
| tree | be71dac5f6eea6629c0a40377a6b6fb2ad14c767 /src/ninep/ctl.zig | |
| parent | 4b64d4b237b2bc5f8197e2232c84c0d1ed1a8fdb (diff) | |
| download | pardes-35e72930c11af5563da9d62df2b74a7439f36653.tar.gz pardes-35e72930c11af5563da9d62df2b74a7439f36653.zip | |
A file changed on disk never reloads over unsaved edits
A watched file rewritten on disk was loaded over a buffer's unsaved edits
and its dirty flag cleared, so Exit and Del no longer asked about them. A
clean buffer still reloads; one with edits keeps its text and stays dirty,
says <file> changed on disk (get reloads it, Save overwrites it), logs
changed <serial>, and its Save warns once before overwriting the newer
file, as acme's Put refuses a file modified since read (exec.c:577); get
asks as ever (winclean, exec.c:513). The restored-watch test's dirty case
now keeps the snapshot, and the filewatch snapshot script (re-recorded
by name) checks both halves: the edited pane keeps its edit and says so,
the clean one reloads.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep/ctl.zig')
| -rw-r--r-- | src/ninep/ctl.zig | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 19ca949e..1b1288a1 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -713,6 +713,7 @@ fn get(p: *Pardes, pane: *Pane) u16 { panes.File.setContent(p, f, bytes); f.saved_revision = f.revision; f.saved_hash = std.hash.Wyhash.hash(0, f.content); + f.disk_newer = null; return 0; } @@ -1558,3 +1559,29 @@ test "a 10k-line Edit text block is taken in linear time and memory" { try testing.expect(p.scratch.queryCapacity() < 50 * 1024 * 1024); try testing.expectEqual(@as(usize, 10_001), std.mem.count(u8, p.panes[0].?.file.?.content, "\n")); } + +test "a file changed on disk under unsaved edits is not reloaded: it says so, get asks, Save warns once" { + const p = try withFile(testing.allocator, "one\n"); + defer p.deinit(); + const serial = serialOf(p); + const f = &p.panes[0].?.file.?; + // Clean, it takes the new text. + pardes.panes.File.changed(p, 0, "two\n"); + try testing.expectEqualStrings("two\n", f.content); + // Edited, it keeps its text and stays dirty. + _ = wr(p, Node.of(serial, .body), "mine\n"); + pardes.panes.File.changed(p, 0, "three\n"); + try testing.expectEqualStrings("two\nmine\n", f.content); + try testing.expect(f.revision != f.saved_revision); + try testing.expect(th.logHas(p, "changed on disk (get reloads it, Save overwrites it)")); + var want: [32]u8 = undefined; + try testing.expect(th.logHas(p, try std.fmt.bufPrint(&want, "changed {d}\n", .{serial}))); + // Exit and get still ask about the edits. + try testing.expectEqual(Status.err, wr(p, @intFromEnum(tree.TopFile.ctl), "Exit\n").reply.status); + try testing.expect(std.mem.indexOf(u8, wr(p, Node.of(serial, .ctl), "get\n").reply.ename, "Modified") != null); + // Save warns once before overwriting the newer file, then writes. + const first = wr(p, Node.of(serial, .ctl), "Save\n"); + try testing.expectEqual(Status.err, first.reply.status); + try testing.expect(std.mem.indexOf(u8, first.reply.ename, "modified on disk since read") != null); + try testing.expect(wr(p, Node.of(serial, .ctl), "Save\n").saved); +} |
