summaryrefslogtreecommitdiff
path: root/src/File.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 17:59:09 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commitcbb6f821c29ede01648cdd41d2f1d2259a387645 (patch)
tree0359efa48c1ec626413c0c939e8c718822a20b5a /src/File.zig
parentc5fcbc0cb9c1e76bb01283e9ccfa00ed5bc4bef8 (diff)
downloadpardes-cbb6f821c29ede01648cdd41d2f1d2259a387645.tar.gz
pardes-cbb6f821c29ede01648cdd41d2f1d2259a387645.zip
Text brought back to what was saved is clean again
dirty compared revisions only, so undoing to the save point, or typing the text back, left the pane dirty. The saved text's hash is kept from the first edit after a save or load, and an edit that makes the text equal to it marks the pane saved again, as undo to the save point does in acme. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/File.zig')
-rw-r--r--src/File.zig9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/File.zig b/src/File.zig
index b8368482..929e33bf 100644
--- a/src/File.zig
+++ b/src/File.zig
@@ -53,6 +53,10 @@ pub const State = struct {
/// Revision last known to match disk, after Save or an external reload.
/// Equal means the screen matches disk.
saved_revision: u32 = 0,
+ /// The text at `saved_revision`, hashed as the first edit after it
+ /// replaces it: an edit that brings the text back to it is clean again,
+ /// as an undo to the save point is in acme.
+ saved_hash: ?u64 = null,
watch_after_save: bool = false,
/// Seconds of the last content change, for the filesystem's stat; zero until edited.
mtime: u32 = 0,
@@ -859,9 +863,14 @@ pub fn setContent(p: *Pardes, f: *State, new: []u8) void {
if (f.mini) |*mini| mini.deinit(p.gpa);
f.mini = null;
const starts: []usize = if (f.line_starts.len > 0) editedLineStarts(p.gpa, f.line_starts, f.content, new) catch &.{} else &.{};
+ // ponytail: a whole-text hash per edit; a rolling hash when files grow large.
+ if (f.revision == f.saved_revision or f.saved_hash == null) f.saved_hash = std.hash.Wyhash.hash(0, f.content);
p.gpa.free(f.content);
f.content = new;
f.revision +%= 1;
+ if (f.saved_hash) |h| if (std.hash.Wyhash.hash(0, new) == h) {
+ f.saved_revision = f.revision;
+ };
f.mtime = pardes.ctlfs.events.now();
if (f.line_starts.len > 0) p.gpa.free(f.line_starts);
f.line_starts = starts;