From b913b8ad87df928b9f6df0a432e2c03e4c040614 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Sat, 9 Aug 2025 19:15:01 +0200 Subject: [PATCH] feat: write early log output to stderr/stdout until TUI is initialized --- src/log.zig | 31 ++++++++++++++++++++++++++++++- src/tui/tui.zig | 4 ++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/log.zig b/src/log.zig index 71d3521..1beff73 100644 --- a/src/log.zig +++ b/src/log.zig @@ -11,6 +11,8 @@ subscriber: ?tp.pid, heap: [32 + 1024]u8, fba: std.heap.FixedBufferAllocator, msg_store: MsgStoreT, +no_stdout: bool = false, +no_stderr: bool = false, const MsgStoreT = std.DoublyLinkedList([]u8); const Receiver = tp.Receiver(*Self); @@ -79,12 +81,23 @@ fn store_reset(self: *Self) void { fn receive(self: *Self, from: tp.pid_ref, m: tp.message) tp.result { errdefer self.deinit(); - if (try m.match(.{ "log", tp.more })) { + var output: []const u8 = undefined; + if (try m.match(.{ "log", "error", tp.string, "std.log", "->", tp.extract(&output) })) { if (self.subscriber) |subscriber| { subscriber.send_raw(m) catch {}; } else { self.store(m); } + if (!self.no_stderr) + std.io.getStdErr().writer().print("{s}\n", .{output}) catch {}; + } else if (try m.match(.{ "log", tp.string, tp.extract(&output) })) { + if (self.subscriber) |subscriber| { + subscriber.send_raw(m) catch {}; + } else { + self.store(m); + } + if (!self.no_stdout) + std.io.getStdOut().writer().print("{s}\n", .{output}) catch {}; } else if (try m.match(.{"subscribe"})) { // log("subscribed"); if (self.subscriber) |*s| s.deinit(); @@ -95,6 +108,14 @@ fn receive(self: *Self, from: tp.pid_ref, m: tp.message) tp.result { if (self.subscriber) |*s| s.deinit(); self.subscriber = null; self.store_reset(); + } else if (try m.match(.{ "stdout", "enable" })) { + self.no_stdout = false; + } else if (try m.match(.{ "stdout", "disable" })) { + self.no_stdout = true; + } else if (try m.match(.{ "stderr", "enable" })) { + self.no_stderr = false; + } else if (try m.match(.{ "stderr", "disable" })) { + self.no_stderr = true; } else if (try m.match(.{"shutdown"})) { return tp.exit_normal(); } @@ -202,6 +223,14 @@ pub fn unsubscribe() tp.result { return tp.env.get().proc("log").send(.{"unsubscribe"}); } +pub fn stdout(state: enum { enable, disable }) void { + tp.env.get().proc("log").send(.{ "stdout", state }) catch {}; +} + +pub fn stderr(state: enum { enable, disable }) void { + tp.env.get().proc("log").send(.{ "stderr", state }) catch {}; +} + var std_log_pid: ?tp.pid_ref = null; pub fn set_std_log_pid(pid: ?tp.pid_ref) void { diff --git a/src/tui/tui.zig b/src/tui/tui.zig index 5aa13f6..3a3e7c8 100644 --- a/src/tui/tui.zig +++ b/src/tui/tui.zig @@ -103,6 +103,8 @@ const InitError = error{ keybind.LoadError; fn init(allocator: Allocator) InitError!*Self { + log.stdout(.disable); + var conf, const conf_bufs = root.read_config(@import("config"), allocator); if (@hasDecl(renderer, "install_crash_handler") and conf.start_debugger_on_crash) @@ -157,6 +159,8 @@ fn init(allocator: Allocator) InitError!*Self { self.rdr_.dispatch_event = dispatch_event; try self.rdr_.run(); + log.stderr(.disable); + try project_manager.start(); try frame_clock.start();