diff options
Diffstat (limited to 'src/dump.zig')
| -rw-r--r-- | src/dump.zig | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/src/dump.zig b/src/dump.zig index 84321457..201f5bf2 100644 --- a/src/dump.zig +++ b/src/dump.zig @@ -232,6 +232,9 @@ pub const File = struct { /// Its dot, q0 and q1 in bytes, as acme's dump keeps a window's; null /// in older dumps. dot: ?[2]u32 = null, + /// A Zerox twin: the index, in `panes`, of the earlier pane whose + /// buffer it shares, its text kept there once; null for none. + twin_of: ?u32 = null, }; pub const ImagePalette = enum { @@ -302,6 +305,8 @@ pub const State = struct { /// config are kept on their own, and the font is the frontend's. Absent /// in older dumps. settings: []const []const u8 = &.{}, + /// Incl's directories, in order; null in older dumps (the defaults). + incl: ?[]const []const u8 = null, }; /// A header is a text like any other: it may hold newlines, but not a @@ -765,6 +770,22 @@ pub fn dumpState(p: *Pardes) !void { dump_panes[panes_len] = dp; panes_len += 1; } + // Zerox's twins: the text once, in the first; each other names it. + for (p.panes, 0..) |slot, id| { + const f = (slot orelse continue).file orelse continue; + if (f.twin == 0) continue; + const i = slot_to_pane[id] orelse continue; + for (p.panes[0..id], 0..) |earlier, j_id| { + const of = (earlier orelse continue).file orelse continue; + if (of.twin != f.twin) continue; + const j = slot_to_pane[j_id] orelse break; + if (dump_panes[i].file) |*df| { + df.twin_of = @intCast(j); + df.content_b64 = ""; + } + break; + } + } var columns: [MAX_COLS]Column = undefined; var columns_len: usize = 0; @@ -798,6 +819,7 @@ pub fn dumpState(p: *Pardes) !void { .panes = dump_panes[0..panes_len], .mounts = mounts[0..p.fs.mounts.items.len], .settings = try changedSettings(p, arena), + .incl = p.incl.items, }; try validate(state); var out: std.Io.Writer.Allocating = .init(p.gpa); @@ -842,6 +864,7 @@ fn applySettings(p: *Pardes, lines: []const []const u8) void { } const setting = config.Runtime.find(line[0 .. sp orelse line.len]) orelse continue; _ = p.settings.apply(setting, if (sp) |s| line[s + 1 ..] else null); + if (setting.action == .tab) config.tab_now = p.settings.tab; } } @@ -902,6 +925,14 @@ fn initDump(gpa: std.mem.Allocator, opts: Options, zon_bytes: []const u8, previo p.locations_config = st.locations_config; p.settings.tree_context_tag_style = st.tree_context_tag_style; applySettings(p, st.settings); + if (st.incl) |dirs| { + for (p.incl.items) |dir| p.gpa.free(dir); + p.incl.clearRetainingCapacity(); + for (dirs) |dir| if (dir.len > 0 and dir[0] == '/' and std.mem.indexOfScalar(u8, dir, 0) == null) { + const copy = p.gpa.dupe(u8, dir) catch continue; + p.incl.append(p.gpa, copy) catch p.gpa.free(copy); + }; + } // A dump naming a ThemeFile asks the host to load it again: until it // has, and for good if it fails, the theme this session showed goes on // (a failed ThemeFile changes nothing, a Restore's included), unless @@ -952,7 +983,12 @@ fn initDump(gpa: std.mem.Allocator, opts: Options, zon_bytes: []const u8, previo if (t.petscii and pardes.panes.terminal.petscii(restored) == false) pardes.panes.terminal.togglePetscii(restored); break :terminal restored; }, - .file => try pardes.panes.File.restore(p, i, src), + .file => file: { + const restored = try pardes.panes.File.restore(p, i, src); + // A twin: on the earlier pane's buffer again. + if (src.file.?.twin_of) |j| if (j < i) pardes.panes.File.relink(p, j, i, src.file.?.dot); + break :file restored; + }, .image => restore_image: { const im = src.image.?; if (pardes.panes.Pdf.isPath(im.path)) { @@ -1028,14 +1064,17 @@ test "a dump keeps the settings that differ from a fresh session's, and a restor defer p.deinit(); try std.testing.expect(p.executeBuiltinLine(p.active, "Placement pardes")); try std.testing.expect(p.executeBuiltinLine(p.active, "Verbose off")); + try std.testing.expect(p.executeBuiltinLine(p.active, "JumpScope all")); try dumpState(p); try std.testing.expect(std.mem.indexOf(u8, p.dump_out.?, "\"Placement pardes\"") != null); + try std.testing.expect(std.mem.indexOf(u8, p.dump_out.?, "\"JumpScope all\"") != null); // What is left at its default is not written. try std.testing.expect(std.mem.indexOf(u8, p.dump_out.?, "\"BootShell keep\"") == null); const restored = try initFromDump(gpa, .{ .tty_only = true }, p.dump_out.?); defer restored.deinit(); try std.testing.expectEqual(config.Runtime.Placement.pardes, restored.settings.placement); try std.testing.expect(!restored.settings.verbose); + try std.testing.expectEqual(config.Runtime.JumpScope.all, restored.settings.jump_scope); } test "a session with every column it may hold dumps and restores them all" { |
