terminal/tmux: better formatting for notifications and actions

pull/9860/head
Mitchell Hashimoto 2025-12-07 14:28:00 -08:00
parent 52dbca3d26
commit b26c42f4a6
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
3 changed files with 52 additions and 4 deletions

View File

@ -531,7 +531,31 @@ pub const Notification = union(enum) {
session_id: usize,
name: []const u8,
},
};
pub fn format(self: Notification, writer: *std.Io.Writer) !void {
const T = Notification;
const info = @typeInfo(T).@"union";
try writer.writeAll(@typeName(T));
if (info.tag_type) |TagType| {
try writer.writeAll("{ .");
try writer.writeAll(@tagName(@as(TagType, self)));
try writer.writeAll(" = ");
inline for (info.fields) |u_field| {
if (self == @field(TagType, u_field.name)) {
const value = @field(self, u_field.name);
switch (u_field.type) {
[]const u8 => try writer.print("\"{s}\"", .{std.mem.trim(u8, value, " \t\r\n")}),
else => try writer.print("{any}", .{value}),
}
}
}
try writer.writeAll(" }");
}
}
};
test "tmux begin/end empty" {
const testing = std.testing;

View File

@ -64,6 +64,30 @@ pub const Viewer = struct {
/// are guaranteed to be stable. Additionally, tmux (as of Dec 2025)
/// never re-uses window IDs within a server process lifetime.
windows: []const Window,
pub fn format(self: Action, writer: *std.Io.Writer) !void {
const T = Action;
const info = @typeInfo(T).@"union";
try writer.writeAll(@typeName(T));
if (info.tag_type) |TagType| {
try writer.writeAll("{ .");
try writer.writeAll(@tagName(@as(TagType, self)));
try writer.writeAll(" = ");
inline for (info.fields) |u_field| {
if (self == @field(TagType, u_field.name)) {
const value = @field(self, u_field.name);
switch (u_field.type) {
[]const u8 => try writer.print("\"{s}\"", .{std.mem.trim(u8, value, " \t\r\n")}),
else => try writer.print("{any}", .{value}),
}
}
}
try writer.writeAll(" }");
}
}
};
pub const Input = union(enum) {

View File

@ -384,7 +384,7 @@ pub const StreamHandler = struct {
// If tmux control mode is disabled at the build level,
// then this whole block shouldn't be analyzed.
if (comptime !tmux_enabled) break :tmux;
log.info("tmux control mode event cmd={}", .{tmux});
log.info("tmux control mode event cmd={f}", .{tmux});
switch (tmux) {
.enter => {
@ -415,7 +415,7 @@ pub const StreamHandler = struct {
// This can only really happen if we failed to
// initialize the viewer on enter.
log.info(
"received tmux control mode command without viewer: {}",
"received tmux control mode command without viewer: {f}",
.{tmux},
);
@ -423,7 +423,7 @@ pub const StreamHandler = struct {
};
for (try viewer.next(.{ .tmux = tmux })) |action| {
log.info("tmux viewer action={}", .{action});
log.info("tmux viewer action={f}", .{action});
switch (action) {
.exit => {
// We ignore this because we will fully exit when