From 558c59368bd08668eb094c076645736c9899d4a9 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Wed, 25 Feb 2026 10:54:46 +0100 Subject: [PATCH] refactor(terminal): report child exit status --- build.zig.zon | 4 ++-- src/tui/terminal_view.zig | 45 ++++++++++++++++++++++++--------------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index 0105f0c..3f13368 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -30,8 +30,8 @@ .hash = "fuzzig-0.1.1-Ji0xivxIAQBD0g8O_NV_0foqoPf3elsg9Sc3pNfdVH4D", }, .vaxis = .{ - .url = "git+https://github.com/neurocyte/libvaxis?ref=main#525cd36ed3e52e5a4787092672bcad728e03487c", - .hash = "vaxis-0.5.1-BWNV_EJOCQCbXYSOktimDKBUitbfuwLJtUOAIP2hD6Xg", + .url = "git+https://github.com/neurocyte/libvaxis?ref=main#c3897fa1b939e5d7a28c5e596d2a77cecc2d4841", + .hash = "vaxis-0.5.1-BWNV_DNOCQDusSCszNwnYmi7HmVWLa1IQJj3TH5oaifJ", }, .zeit = .{ .url = "git+https://github.com/rockorager/zeit?ref=zig-0.15#ed2ca60db118414bda2b12df2039e33bad3b0b88", diff --git a/src/tui/terminal_view.zig b/src/tui/terminal_view.zig index 3f4bbda..a33c473 100644 --- a/src/tui/terminal_view.zig +++ b/src/tui/terminal_view.zig @@ -198,9 +198,9 @@ pub fn render(self: *Self, _: *const Widget.Theme) bool { // Drain the vt event queue. while (self.vt.tryEvent()) |event| { switch (event) { - .exited => { - tp.self_pid().send(.{ "cmd", "toggle_terminal_view" }) catch {}; - return false; + .exited => |code| { + self.show_exit_message(code); + tui.need_render(@src()); }, .redraw, .bell => {}, .pwd_change => |path| { @@ -222,6 +222,21 @@ pub fn render(self: *Self, _: *const Widget.Theme) bool { return false; } +fn show_exit_message(self: *Self, code: u8) void { + var msg: std.Io.Writer.Allocating = .init(self.allocator); + defer msg.deinit(); + const w = &msg.writer; + w.writeAll("\r\n") catch {}; + w.writeAll("\x1b[0m\x1b[2m") catch {}; + w.writeAll("[process exited") catch {}; + if (code != 0) + w.print(" with code {d}", .{code}) catch {}; + w.writeAll("]\x1b[0m\r\n") catch {}; + var parser: pty.Parser = .{ .buf = .init(self.allocator) }; + defer parser.buf.deinit(); + _ = self.vt.processOutput(&parser, msg.written()) catch {}; +} + pub fn handle_resize(self: *Self, pos: Widget.Box) void { self.plane.move_yx(@intCast(pos.y), @intCast(pos.x)) catch return; self.plane.resize_simple(@intCast(pos.h), @intCast(pos.w)) catch return; @@ -297,8 +312,7 @@ const pty = struct { } if (try m.match(.{ "pty_actor", "quit" })) { - self.deinit(); - return; + return tp.exit_normal(); } } @@ -309,28 +323,25 @@ const pty = struct { const n = std.posix.read(self.vt.ptyFd(), &buf) catch |e| switch (e) { error.WouldBlock => break, error.InputOutput => { - self.vt.event_queue.push(.exited); - self.vt.cmd.wait(); - self.deinit(); - return; + const code = self.vt.cmd.wait(); + self.vt.event_queue.push(.{ .exited = code }); + self.parent.send(.{ "terminal_view", "output" }) catch {}; + return tp.exit_normal(); }, else => return tp.exit_error(e, @errorReturnTrace()), }; if (n == 0) { - self.vt.event_queue.push(.exited); - self.vt.cmd.wait(); - self.deinit(); - return; + const code = self.vt.cmd.wait(); + self.vt.event_queue.push(.{ .exited = code }); + self.parent.send(.{ "terminal_view", "output" }) catch {}; + return tp.exit_normal(); } const exited = self.vt.processOutput(&self.parser, buf[0..n]) catch |e| return tp.exit_error(e, @errorReturnTrace()); if (exited) { - self.vt.cmd.wait(); - // Notify parent so it drains the .exited event on its next render. self.parent.send(.{ "terminal_view", "output" }) catch {}; - self.deinit(); - return; + return tp.exit_normal(); } // Notify parent that new output is available. self.parent.send(.{ "terminal_view", "output" }) catch {};