summaryrefslogtreecommitdiff
path: root/src/file_watch.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 05:29:45 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:16 -0300
commit24729dbbf8b32966a3f33c9bc20599b185856dd3 (patch)
treef5c0632b49a61b27334c42ab5ad0fdb74df35821 /src/file_watch.zig
parenteba47199a51370c9753798fbd2439a85ddc4e5bb (diff)
downloadpardes-24729dbbf8b32966a3f33c9bc20599b185856dd3.tar.gz
pardes-24729dbbf8b32966a3f33c9bc20599b185856dd3.zip
get and a deleted file say what happened: the path, changed <serial> deleted, reloaded
get on a file gone from disk failed with a bare ENOENT; it now says get: <path>: no such file. A watched file deleted on disk was silent; the pane keeps its text and says <file> deleted on disk (Save writes it again) once, logged changed <serial> deleted (only a path the watch has read: a pane renamed to a name never on disk is not deleted). A get that throws a dirty buffer's state away logs changed <serial> reloaded, as the watch's reload does. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/file_watch.zig')
-rw-r--r--src/file_watch.zig12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/file_watch.zig b/src/file_watch.zig
index b262e8ce..71a4680d 100644
--- a/src/file_watch.zig
+++ b/src/file_watch.zig
@@ -60,6 +60,10 @@ pub const Watch = struct {
kq: c_int = -1,
serial: u32,
generation: Generation,
+ /// The path last read while watched (its hash): its going away later is
+ /// a deletion to say, where a path never there (a pane renamed to a new
+ /// name) is not.
+ existed: ?u64 = null,
};
/// The final slot is the one non-pane watched payload: the active ThemeFile.
@@ -440,7 +444,12 @@ pub fn reloadPane(
}
if (pane.file) |file| {
- const bytes = filesystem.read(core, file.path) catch return false;
+ const bytes = filesystem.read(core, file.path) catch |err| {
+ // Gone from under the pane: said once, the text kept.
+ if (err == error.FileNotFound and watched.existed == std.hash.Wyhash.hash(0, file.path)) pardes.panes.File.deleted(core, @intCast(id));
+ return false;
+ };
+ if (watches[id]) |*live| live.existed = std.hash.Wyhash.hash(0, file.path);
defer core.gpa.free(bytes);
const hash = std.hash.Wyhash.hash(0, bytes);
switch (watched.generation) {
@@ -517,6 +526,7 @@ pub fn applyEffect(
const bytes = filesystem.read(core, file.path) catch return false;
defer core.gpa.free(bytes);
watched.generation = .{ .text = std.hash.Wyhash.hash(0, bytes) };
+ watched.existed = std.hash.Wyhash.hash(0, file.path);
return false;
};
return on and watches[id] != null and reloadPane(core, io, watches, id, false);