summaryrefslogtreecommitdiff
path: root/src/File.zig
diff options
context:
space:
mode:
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;