summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ninep/pty.zig7
-rw-r--r--src/terminal.zig28
2 files changed, 29 insertions, 6 deletions
diff --git a/src/ninep/pty.zig b/src/ninep/pty.zig
index 2245255b..fc8eb570 100644
--- a/src/ninep/pty.zig
+++ b/src/ninep/pty.zig
@@ -971,13 +971,12 @@ test "a run's answer says cut when its output's start is gone, and reads a bound
defer gpa.free(into);
sh.put(p, prompt);
- // `clear` while it runs erases what it printed before, and the pins then
- // span rows that no longer hold it (ED 3 even moves one to the next page
- // without calling it garbage), so only the erase itself tells.
+ // `clear` while it runs: what it printed after is its output, whole;
+ // what the clear erased was meant to go.
var h = sh.send(p, node);
sh.put(p, c ++ "before\r\n\x1b[H\x1b[2J\x1b[3Jafter\r\n" ++ d ++ prompt);
var got = sh.answered(p, node, h, into);
- try testing.expect(std.mem.startsWith(u8, got, "exit 0 cut\n"));
+ try testing.expectEqualStrings("exit 0\nafter\n", got);
// A resize between its start and end reflows the pins with the text.
diff --git a/src/terminal.zig b/src/terminal.zig
index 0850267e..a0337ce7 100644
--- a/src/terminal.zig
+++ b/src/terminal.zig
@@ -106,12 +106,36 @@ pub const MarkedHandler = if (enabled) struct {
else => {},
}
}
- if (comptime action == .erase_display_complete or action == .erase_display_scrollback or action == .full_reset) {
- if (self.phase == .running) self.lost = true;
+ if (comptime action == .erase_display_complete or action == .erase_display_scrollback or
+ action == .erase_display_scroll_complete or action == .full_reset)
+ {
+ self.inner.vt(action, value);
+ // A `clear` under a running command: its output is what it
+ // prints from here, the screen's top, not lost. Only what the
+ // scrollback later loses is (the pin goes `garbage`).
+ if (self.phase == .running) self.pinTop(&self.out_start);
+ return;
}
self.inner.vt(action, value);
}
+ /// Pins `slot` to the primary screen's top-left; lost when it cannot be.
+ fn pinTop(self: *@This(), slot: *?*ghostty_vt.Pin) void {
+ const screen = self.inner.terminal.screens.get(.primary) orelse return;
+ if (slot.*) |old| screen.pages.untrackPin(old);
+ slot.* = null;
+ if (self.inner.terminal.screens.active_key != .primary) {
+ self.lost = true;
+ return;
+ }
+ const top = screen.pages.pin(.{ .active = .{} }) orelse {
+ self.lost = true;
+ return;
+ };
+ slot.* = screen.pages.trackPin(top) catch null;
+ if (slot.* == null) self.lost = true;
+ }
+
pub fn deinit(self: *@This()) void {
self.inner.deinit();
}