summaryrefslogtreecommitdiff
path: root/src/file_pane.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-08-25 02:07:23 -0300
committerGabriel Schneider <[email protected]>2026-08-25 09:42:07 -0300
commit6f48508aa08396bcf9dd4da2cab1d221bcc53f78 (patch)
tree83daec3db5ac27ea3172651df2b3e9cb62eddb4a /src/file_pane.zig
parent28c70cabb6ceb7e5fecfd74f6984f5a995269f01 (diff)
downloadpardes-6f48508aa08396bcf9dd4da2cab1d221bcc53f78.tar.gz
pardes-6f48508aa08396bcf9dd4da2cab1d221bcc53f78.zip
acmefs: pardes --fs serves acme's control filesystem over raw Linux FUSE
Diffstat (limited to 'src/file_pane.zig')
-rw-r--r--src/file_pane.zig26
1 files changed, 25 insertions, 1 deletions
diff --git a/src/file_pane.zig b/src/file_pane.zig
index 80c31edb..be3ff201 100644
--- a/src/file_pane.zig
+++ b/src/file_pane.zig
@@ -388,9 +388,33 @@ pub fn deinit(p: *Pardes, pane: *Pane, file: *State) void {
for (file.redo[0..file.redo_len]) |snap| p.gpa.free(snap.content);
}
+/// TELL A SCRIPT WHAT CHANGED, when one is listening.
+///
+/// acme reports edits from the two places that make them — `textinsert` and
+/// `textdelete`, which already know their range — so a replacement arrives as
+/// a `D` record and then an `I`. pardes has no such pair: every edit lands
+/// here as a whole new buffer, so the range is recovered by DIFFING, and
+/// `acmefs.noteReplace` owns both the diff and the D-then-I order.
+///
+/// The cost is two vectorised scans of the content, and it is paid only while
+/// a script holds an `event` file open (`p.fs.listeners`); the editor nobody
+/// is scripting does one branch. The pane lookup is a walk of at most
+/// MAX_PANES slots comparing the FILE pointer — a file pane's state is stored
+/// inline in its pane, so that identifies the pane exactly.
+fn reportEdit(p: *Pardes, f: *State, new: []const u8) void {
+ if (p.fs.listeners == 0) return;
+ const id = for (p.panes, 0..) |slot, i| {
+ const pane = slot orelse continue;
+ if (pane.file) |*state| if (state == f) break i;
+ } else return;
+ pardes.acmefs.noteReplace(p, id, false, f.content, new);
+}
+
/// The ONE content swap. Everything that edits a file pane lands here, which
-/// is what lets the line index above have a single invalidation point.
+/// is what lets the line index above have a single invalidation point — and
+/// is why one diff HERE is every body edit a script can be told about.
pub fn setContent(p: *Pardes, f: *State, new: []u8) void {
+ reportEdit(p, f, new);
p.gpa.free(f.content);
f.content = new;
f.revision +%= 1;