diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 00:54:58 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:15 -0300 |
| commit | e988d4e24bfc0b80285754359b4b86f1b15b33f6 (patch) | |
| tree | 7a0e62703f7da558e8695bcf5e2432ff1e52a464 /src | |
| parent | 7aa057e29b729ad6d9ac53e3a06f99858fc449e4 (diff) | |
| download | pardes-e988d4e24bfc0b80285754359b4b86f1b15b33f6.tar.gz pardes-e988d4e24bfc0b80285754359b4b86f1b15b33f6.zip | |
Restore keeps each pane's dot, as acme's dump does
A restored text pane came back with its caret at its view's top, whatever
had been selected. The dump now keeps each text pane's dot, q0 and q1 as
acme's keeps a window's, and Restore puts it back without moving the view
it kept. Two look-walk tests that restored and walked on now start from the
match they were on.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src')
| -rw-r--r-- | src/File.zig | 8 | ||||
| -rw-r--r-- | src/dump.zig | 24 |
2 files changed, 32 insertions, 0 deletions
diff --git a/src/File.zig b/src/File.zig index 929e33bf..6a1ac319 100644 --- a/src/File.zig +++ b/src/File.zig @@ -814,6 +814,14 @@ pub fn restore(p: *Pardes, id: usize, src: dump.Pane) !*Pane { pane.file.?.tree_context = saved.tree_context and supportsContext(pane); pane.body.cur_pinned = true; pane.body.cur_row = @intCast(src.scroll); + // Its dot as it was, where the view the dump kept shows it. + if (saved.dot) |dot| if (dot[0] <= dot[1] and dot[1] <= content.len) { + const a = modal.positionAt(content, dot[0]); + const h = modal.positionAt(content, if (dot[1] > dot[0]) modal.prevGrapheme(content, dot[1]) else dot[0]); + pane.body.vsel = .{ .active = dot[1] > dot[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); + }; pane.cols = @max(1, src.cols); pane.rows = @max(1, src.rows); if (output == null and filesystem.localPath(path) != null) p.emit(.{ .watch = .{ .pane = @intCast(id), .on = true, .mode = .baseline_disk } }); diff --git a/src/dump.zig b/src/dump.zig index 5b0983ad..7101b708 100644 --- a/src/dump.zig +++ b/src/dump.zig @@ -142,6 +142,9 @@ pub const File = struct { origin_arg: []const u8 = "", mini_source: []const u8 = "", mini_colors_b64: []const u8 = "", + /// Its dot, q0 and q1 in bytes, as acme's dump keeps a window's; null + /// in older dumps. + dot: ?[2]u32 = null, }; pub const ImagePalette = enum { @@ -653,6 +656,10 @@ pub fn dumpState(p: *Pardes) !void { else try pardes.panes.Terminal.dumpPane(pane, arena, tag, body, scroll); dp.tag_tail = pane.tag.own; + if (dp.file) |*df| { + const dot = ctlfs.pane.dotOf(pane); + df.dot = .{ dot.q0, dot.q1 }; + } dp.serial = pane.serial; dump_panes[panes_len] = dp; panes_len += 1; @@ -918,3 +925,20 @@ test "a dump keeps the settings that differ from a fresh session's, and a restor try std.testing.expectEqual(config.Runtime.Placement.pardes, restored.settings.placement); try std.testing.expect(!restored.settings.verbose); } + +test "a restored pane keeps its dot, as acme's dump keeps a window's" { + const gpa = std.testing.allocator; + const p = try Pardes.init(gpa, .{ .tty_only = true }); + defer p.deinit(); + const pane = try p.setTestFile("one two three\nfour\n"); + ctlfs.pane.setDot(pane, .{ .q0 = 4, .q1 = 7 }); + try dumpState(p); + const restored = try initFromDump(gpa, .{ .tty_only = true }, p.dump_out.?); + defer restored.deinit(); + const again = for (restored.panes) |slot| { + if (slot) |candidate| if (candidate.file != null) break candidate; + } else return error.FileLost; + const dot = ctlfs.pane.dotOf(again); + try std.testing.expectEqual(@as(u32, 4), dot.q0); + try std.testing.expectEqual(@as(u32, 7), dot.q1); +} |
