From f7e3441698a4621bec0d7c14eb45303753ffbead Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Tue, 29 Sep 2026 08:09:08 -0300 Subject: A rename alone does not make a pane dirty Any rename marked the pane dirty (saved revision one back), while the guards ask only whether its text was ever edited: /index said dirty for a pane Exit let go without asking. The name is no edit now, so /index, the guards and Restore agree; Save writes under the new name all the same. Co-Authored-By: Claude Opus 5.5 --- src/ninep/ctl.zig | 7 ++++--- src/ninep/pane.zig | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src/ninep') diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 0b1ec194..8cf4f0a8 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -1417,9 +1417,10 @@ test "get reloads the pane from disk and reports a missing file without losing d try testing.expectEqualStrings("from disk\n", pane.file.?.content); try testing.expect(!pane_files.dirtyOf(pane)); try testing.expect(pane.file.?.history.undo_len > 0); - // What it had (renamed, so dirty) was thrown away for it: logged. + // Renamed but never edited, it was clean: nothing thrown away, nothing + // logged as reloaded over edits. var reloaded: [32]u8 = undefined; - try testing.expect(th.logHas(p, try std.fmt.bufPrint(&reloaded, "changed {d} reloaded\n", .{serial}))); + try testing.expect(!th.logHas(p, try std.fmt.bufPrint(&reloaded, "changed {d} reloaded\n", .{serial}))); _ = wr(p, Node.of(serial, .name), try std.fmt.bufPrint(&name, "{s}/missing.txt\n", .{directory})); _ = wr(p, Node.of(serial, .body), "unsaved\n"); @@ -1440,7 +1441,7 @@ test "exec Save writes the named file through the host" { const serial = serialOf(p); const pane = p.panes[0].?; try testing.expectEqual(Status.ok, wr(p, Node.of(serial, .name), "/tmp/renamed.txt\n").reply.status); - try testing.expect(pane_files.dirtyOf(pane)); + try testing.expect(!pane_files.dirtyOf(pane)); // a name alone is no edit; Save writes all the same const saved = wr(p, Node.of(serial, .exec), "Save\n"); try testing.expectEqual(Status.ok, saved.reply.status); try testing.expect(saved.saved); diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig index d8329ccc..5f8fc00a 100644 --- a/src/ninep/pane.zig +++ b/src/ninep/pane.zig @@ -636,7 +636,9 @@ pub fn nameBuffer(p: *Pardes, id: usize, full: []const u8, preserve_tag: bool) ! if (pane.tag.own) |own| p.gpa.free(own); pane.tag.own = null; } - f.saved_revision = f.revision -% 1; + // A name alone is no edit: dirty stays what the text made it, as + // the guards ask only whether it was ever edited, so /index, Exit + // and Restore agree. Save writes it under the new name all the same. f.watch_after_save = fs.localPath(full) != null; } if (f.highlights.len > 0) p.tree_sitter_gpa.free(f.highlights); @@ -1151,7 +1153,7 @@ test "relative names use the file directory and can name a new target" { var expected_buf: [4096]u8 = undefined; const expected = try std.fmt.bufPrint(&expected_buf, "{s}/created.txt", .{directory}); try testing.expectEqualStrings(expected, pane.file.?.path); - try testing.expect(dirtyOf(pane)); + try testing.expect(!dirtyOf(pane)); // a name alone is no edit } test "relative names follow a pane/new scratch's session directory and virtual directories" { -- cgit v1.3