diff options
Diffstat (limited to 'src/File.zig')
| -rw-r--r-- | src/File.zig | 9 |
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; |
