diff options
Diffstat (limited to 'src/dump.zig')
| -rw-r--r-- | src/dump.zig | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/src/dump.zig b/src/dump.zig index 8e669b77..ef442ddb 100644 --- a/src/dump.zig +++ b/src/dump.zig @@ -99,6 +99,13 @@ pub const PaneKind = enum { pub const Terminal = struct { cwd: []const u8 = "", + /// The shell it runs when not the configured one (`Tty bash`); empty, + /// the configured one, as in dumps from before. + shell: []const u8 = "", + /// A command pane's line and how it ended (null: unknown, or still + /// running when dumped); empty for an interactive terminal. + command: []const u8 = "", + status: ?u8 = null, /// The rendered scrollback and screen as plain text, one row per line. stream: []const u8 = "", stream_b64: []const u8 = "", @@ -161,6 +168,9 @@ pub const Pane = struct { rows: u16 = 0, vweight: f32 = 1, collapsed: bool = false, + /// Its serial when dumped (0 in older dumps): a Restore logs + /// `restored <old> <new>` for it. + serial: u32 = 0, /// Exact editable tail when the user touched it. Null retains the live /// default; a present empty slice deliberately restores an empty tail. tag_tail: ?[]const u8 = null, @@ -626,6 +636,7 @@ pub fn dumpState(p: *Pardes) !void { else try pardes.panes.Terminal.dumpPane(pane, arena, tag, body, scroll); dp.tag_tail = pane.tag.own; + dp.serial = pane.serial; dump_panes[panes_len] = dp; panes_len += 1; } @@ -676,16 +687,22 @@ pub fn restore(p: *Pardes, zon_bytes: []const u8, from: []const u8) !*Pardes { var opts = p.opts; opts.cols = p.screen_w; opts.rows = p.screen_h; - const replacement = try initDump(p.gpa, opts, zon_bytes, p); + var old: [MAX_PANES]u32 = @splat(0); + const replacement = try initDump(p.gpa, opts, zon_bytes, p, &old); pardes.ctlfs.events.notePath(replacement, "restore", from); + // Which serial each pane had, for a script that held the old ones. + for (replacement.panes, old) |slot, was| if (slot) |pane| if (was != 0) { + var rec: [32]u8 = undefined; + pardes.ctlfs.events.notePath(replacement, "restored", std.fmt.bufPrint(&rec, "{d} {d}", .{ was, pane.serial }) catch continue); + }; return replacement; } pub fn initFromDump(gpa: std.mem.Allocator, opts: Options, zon_bytes: []const u8) !*Pardes { - return initDump(gpa, opts, zon_bytes, null); + return initDump(gpa, opts, zon_bytes, null, null); } -fn initDump(gpa: std.mem.Allocator, opts: Options, zon_bytes: []const u8, previous: ?*const Pardes) !*Pardes { +fn initDump(gpa: std.mem.Allocator, opts: Options, zon_bytes: []const u8, previous: ?*const Pardes, old_serials: ?*[MAX_PANES]u32) !*Pardes { const image_gpa = opts.image_allocator orelse gpa; const pdf_gpa = opts.pdf_allocator orelse gpa; const tree_sitter_gpa = opts.tree_sitter_allocator orelse gpa; @@ -735,17 +752,26 @@ fn initDump(gpa: std.mem.Allocator, opts: Options, zon_bytes: []const u8, previo } for (st.panes, 0..) |src, i| { if (i >= MAX_PANES) break; + if (old_serials) |o| o[i] = src.serial; const pane: *pardes.panes.Pane = switch (src.kind) { .terminal => terminal: { const t = src.terminal.?; // A host that runs shells gets them back: the old history // above a new shell in the directory it was in. The web // shell and an isolated build only ever replay it. + // A command pane comes back finished, showing what it said + // and how it ended: its command is not run again. const live = comptime (terminal_panes and platform != .web and !isolated); - const revive = live and t.cwd.len <= effect_path_cap; + const revive = live and t.cwd.len <= effect_path_cap and t.command.len == 0; const restored = try pardes.panes.Terminal.restore(p, src, revive); p.installPane(i, restored); try restored.setOwnedCwd(t.cwd); + if (t.shell.len > 0) restored.shell = try gpa.dupe(u8, t.shell); + if (t.command.len > 0) { + restored.command = try gpa.dupe(u8, t.command); + restored.command_done = true; + restored.command_status = t.status; + } if (std.mem.startsWith(u8, src.tag, "TTY ")) restored.body.mode = .tty; if (revive) p.emit(.{ .spawn = .{ .pane = @intCast(i), .serial = restored.serial, .cwd = .from(t.cwd) } }); break :terminal restored; |
