summaryrefslogtreecommitdiff
path: root/src/File.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-30 21:16:32 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:17 -0300
commitf02c10bfa6d02d305ddb6d7a28b12c40035274c7 (patch)
tree1fe0e159cd3d24f0ed67d3358e3d6bcab9741cf7 /src/File.zig
parenta2c719779c9ce0f676fb159135675df6275e77bf (diff)
downloadpardes-f02c10bfa6d02d305ddb6d7a28b12c40035274c7.tar.gz
pardes-f02c10bfa6d02d305ddb6d7a28b12c40035274c7.zip
A Restore brings back clean a pane whose file was never on disk, such as Config's new init; only a file that existed when dumped is said deleted
A restored pane whose path was not on disk was marked deleted on disk, so Config's not-yet-written init came back dirty and asked before Del, Exit or Restore. The dump now records whether the file was on disk (older dumps read as yes), and only one that was and is gone is said deleted. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/File.zig')
-rw-r--r--src/File.zig31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/File.zig b/src/File.zig
index a89db613..d16d4fc0 100644
--- a/src/File.zig
+++ b/src/File.zig
@@ -127,6 +127,7 @@ pub fn dumpPane(
.content = file.content,
.content_b64 = try dump.encodeBytes(arena, file.content),
.dirty = file.revision != file.saved_revision,
+ .on_disk = onDisk(file.path),
.origin = origin,
.origin_arg = origin_arg,
.mini_source = if (file.mini) |mini| mini.source else "",
@@ -220,6 +221,24 @@ fn restoreLocationRows(gpa: std.mem.Allocator, content: []const u8, saved: []con
return rows;
}
+test "a clean pane whose file was never on disk comes back clean from a Restore; one whose file has gone is said deleted" {
+ if (comptime !pardes.hosted) return;
+ for ([_]bool{ false, true }) |was_on_disk| {
+ const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true });
+ defer p.deinit();
+ while (p.nextEffect()) |_| {}
+ const id = p.freeSlot().?;
+ const pane = try restore(p, id, .{
+ .kind = .file,
+ .tag = "",
+ .body = "",
+ .file = .{ .path = "/tmp/pardes-never-written/init", .content = "", .on_disk = was_on_disk },
+ });
+ try std.testing.expectEqual(was_on_disk, pane.file.?.disk_gone);
+ try std.testing.expectEqual(pane.file.?.saved_revision, pane.file.?.revision);
+ }
+}
+
test "location metadata restore rejects offsets and invalid syntax bytes" {
const gpa = std.testing.allocator;
var row: dump.LocationRow = .{
@@ -898,11 +917,19 @@ pub fn restore(p: *Pardes, id: usize, src: dump.Pane) !*Pane {
// Its file gone from disk since the dump: its text is nowhere else now,
// so it comes back as one deleted on disk, dirty, and Del, Exit and
// Restore ask before throwing it away.
- if (comptime pardes.hosted) if (output == null) if (filesystem.localPath(path)) |local|
- if (@import("exec.zig").kindOf(local) == null) deleted(p, @intCast(id));
+ // One never on disk (Config's new file, a name not yet saved) is
+ // restored as it was: clean, and nothing deleted.
+ if (output == null and saved.on_disk and !onDisk(path)) deleted(p, @intCast(id));
return pane;
}
+/// Whether `path` names a file on this host's disk now.
+fn onDisk(path: []const u8) bool {
+ if (comptime !pardes.hosted) return false;
+ const local = filesystem.localPath(path) orelse return false;
+ return @import("exec.zig").kindOf(local) != null;
+}
+
pub fn deinit(p: *Pardes, pane: *Pane, file: *State) void {
if (file.output == null) for (p.panes, 0..) |slot, id| {
if (slot == pane) p.emit(.{ .watch = .{ .pane = @intCast(id), .on = false } });