diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-28 15:57:07 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:15 -0300 |
| commit | 2d24ae98621f24c869ced4dbc06146086ff14887 (patch) | |
| tree | fc7d12afe0acd9f8357994bc977cd1854503daca | |
| parent | b67dce15e662ae44de3286686f5a0afc147b918d (diff) | |
| download | pardes-2d24ae98621f24c869ced4dbc06146086ff14887.tar.gz pardes-2d24ae98621f24c869ced4dbc06146086ff14887.zip | |
A restored terminal's tag names neither the REPL it was nor the shell it had
A dump keeps a terminal's whole tag, and restoring read its tail from it
after the directory: the REPL id and Tty+fish, which were live facts and not
the tag's text, came back as a custom tail, so the tags said python-a over a
fresh shell bound to nothing. Restoring now sees through the id and the
shell in the Tty word, a default tail stays the default, and the new shell
names itself when it starts.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | src/pardes.zig | 19 | ||||
| -rw-r--r-- | src/tagline.zig | 20 |
2 files changed, 38 insertions, 1 deletions
diff --git a/src/pardes.zig b/src/pardes.zig index f8328289..43d8e94d 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -1544,6 +1544,25 @@ test "a REPL bound for a language takes the exec made on a body in it; tags, Exe try std.testing.expect(doc.repl == null); } +test "a restored terminal's tag names neither the REPL it was nor the shell it had" { + const gpa = std.testing.allocator; + const p = try Pardes.init(gpa, .{ .tty_only = true }); + defer p.deinit(); + while (p.nextEffect()) |_| {} + p.acknowledgeShell(0, "/usr/bin/fish", true); + var host: FakeTtyQuery = .{}; + host.install(p); + try std.testing.expect(p.executeBuiltinLine(0, "Repl python")); + try dump.dumpState(p); + const restored = try dump.restore(p, p.dump_out.?, "test"); + defer restored.deinit(); + const pane = restored.panes[0].?; + try std.testing.expect(pane.repl == null and pane.tag.own == null); + const shown = try tagline.tagText(restored, restored.scratch.allocator(), pane); + try std.testing.expect(std.mem.indexOf(u8, shown, "python-a") == null); + try std.testing.expect(std.mem.indexOf(u8, shown, "Tty+fish") == null); +} + test "Tty+fish, one word a tag can hold, opens a terminal on that shell" { const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true }); defer p.deinit(); diff --git a/src/tagline.zig b/src/tagline.zig index 28dffa06..6d5992f1 100644 --- a/src/tagline.zig +++ b/src/tagline.zig @@ -416,8 +416,26 @@ pub fn restoreTailAt( }, .terminal => &.{ terminal_pane_tail, pre_close_last_terminal_pane_tail, pre_close_last_pane_tail, pre_mode_terminal_pane_tail, pre_tty_first_terminal_pane_tail, pre_collapse_terminal_pane_tail, pre_column_terminal_pane_tail, pre_tty_terminal_pane_tail, prev_terminal_pane_tail, legacy_terminal_pane_tail, pane_tail, pre_collapse_pane_tail, pre_column_pane_tail, prev_pane_tail, legacy_pane_tail }, }; + // A terminal's saved tag carries what was live about it -- the REPL id + // after its directory, the shell in its Tty word -- which is neither + // dumped nor true of the new shell: its tail is still the default. + var plain = said; + var plain_buf: [256]u8 = undefined; + if (class == .terminal) { + const first = plain[0 .. std.mem.indexOfScalar(u8, plain, ' ') orelse plain.len]; + if (std.mem.lastIndexOfScalar(u8, first, '-')) |dash| if (dash + 2 == first.len and first[dash + 1] >= 'a' and first[dash + 1] <= 'z') { + for (@import("grammar_manifest.zig").all) |g| if (std.mem.eql(u8, g.name, first[0..dash])) { + plain = std.mem.trimStart(u8, plain[first.len..], " "); + break; + }; + }; + if (std.mem.startsWith(u8, plain, "Tty+")) { + const word_end = std.mem.indexOfScalar(u8, plain, ' ') orelse plain.len; + plain = std.fmt.bufPrint(&plain_buf, "Tty{s}", .{plain[word_end..]}) catch plain; + } + } for (defaults) |default| - if (std.mem.eql(u8, said, std.mem.trimStart(u8, default, " "))) return; + if (std.mem.eql(u8, plain, std.mem.trimStart(u8, default, " "))) return; pane.tag.own = p.gpa.dupe(u8, rest) catch return; } |
