summaryrefslogtreecommitdiff
path: root/src/File.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-10-01 20:53:19 -0300
committerGabriel Schneider <[email protected]>2026-10-01 20:53:19 -0300
commit778de441bc5645bf15ba8d3dff83766fbb70499e (patch)
treed6ebd1a202abc2ff5574db8ca11c417d466919eb /src/File.zig
parent081e1b9ab9d3bb8afaae8ea040c7767cb6e4f863 (diff)
downloadpardes-778de441bc5645bf15ba8d3dff83766fbb70499e.tar.gz
pardes-778de441bc5645bf15ba8d3dff83766fbb70499e.zip
Zerox twins survive a Dump and Restore: their text is dumped once, in the first, each other twin names it (twin_of), and Restore puts them back on one buffer with their dots
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/File.zig')
-rw-r--r--src/File.zig41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/File.zig b/src/File.zig
index 0f1579b2..e5805134 100644
--- a/src/File.zig
+++ b/src/File.zig
@@ -1275,6 +1275,47 @@ pub fn leaveTwins(p: *Pardes, f: *State) void {
if (n == 1) p.panes[twins[0]].?.file.?.twin = 0;
}
+/// Restore's: pane `id`, restored on its own, back on pane `of`'s buffer
+/// as the Zerox twin it was dumped as (dump.File.twin_of). Not a file pane
+/// there (a dump edited by hand), it stays on its own.
+pub fn relink(p: *Pardes, of: usize, id: usize, dot: ?[2]u32) void {
+ const src = p.panes[of] orelse return;
+ const pane = p.panes[id] orelse return;
+ const sf = if (src.file) |*file| file else return;
+ const f = if (pane.file) |*file| file else return;
+ if (sf.output != null or f.output != null or sf.mini != null) return;
+ if (sf.twin == 0) {
+ const group = p.gpa.dupe(u8, sf.path) catch return;
+ p.twin_groups.append(p.gpa, .{ .id = p.next_twin, .saved_revision = sf.saved_revision, .saved_hash = sf.saved_hash, .saved_len = sf.saved_len, .disk_newer = sf.disk_newer, .disk_gone = sf.disk_gone, .path = group }) catch return p.gpa.free(group);
+ sf.twin = p.next_twin;
+ p.next_twin +%= 1;
+ }
+ p.gpa.free(f.content);
+ if (f.line_starts.len > 0) p.gpa.free(f.line_starts);
+ for (f.history.undo[0..f.history.undo_len]) |snap| snap.deinit(p.gpa);
+ for (f.history.redo[0..f.history.redo_len]) |snap| snap.deinit(p.gpa);
+ p.gpa.destroy(f.history);
+ f.content = sf.content;
+ f.line_starts = sf.line_starts;
+ f.history = sf.history;
+ f.revision = sf.revision;
+ f.saved_revision = sf.saved_revision;
+ f.saved_hash = sf.saved_hash;
+ f.saved_len = sf.saved_len;
+ f.twin = sf.twin;
+ if (f.highlights.len > 0) p.tree_sitter_gpa.free(f.highlights);
+ f.highlights = &.{};
+ f.syntax_dirty = true;
+ // Its dot as dumped, read now that its text is back.
+ if (dot) |d| if (d[0] <= d[1] and d[1] <= f.content.len) {
+ const a = modal.positionAt(f.content, d[0]);
+ const h = modal.positionAt(f.content, if (d[1] > d[0]) modal.prevGrapheme(f.content, d[1]) else d[0]);
+ pane.body.vsel = .{ .active = d[1] > d[0], .row = @intCast(a.row), .col = @intCast(a.col), .explicit = true };
+ pane.body.cur_row = @intCast(h.row);
+ pane.body.cur_col = @intCast(h.col);
+ };
+}
+
pub const TwinGroup = struct {
id: u32,
saved_revision: u32,