From 6369f1f2f9290b6142788ec1e3971604673e61db Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 24 Jul 2022 09:20:02 -0700 Subject: [PATCH] big improvements in action logging --- src/terminal/Parser.zig | 64 +++++++++++++++++++++++++++++++++++++++++ src/terminal/stream.zig | 5 +--- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/terminal/Parser.zig b/src/terminal/Parser.zig index b3b8b84b0..cd77007e9 100644 --- a/src/terminal/Parser.zig +++ b/src/terminal/Parser.zig @@ -99,6 +99,21 @@ pub const Action = union(enum) { pub const ESC = struct { intermediates: []u8, final: u8, + + // Implement formatter for logging + pub fn format( + self: ESC, + comptime layout: []const u8, + opts: std.fmt.FormatOptions, + writer: anytype, + ) !void { + _ = layout; + _ = opts; + try std.fmt.format(writer, "ESC {s} {c}", .{ + self.intermediates, + self.final, + }); + } }; pub const DCS = struct { @@ -106,6 +121,55 @@ pub const Action = union(enum) { params: []u16, final: u8, }; + + // Implement formatter for logging. This is mostly copied from the + // std.fmt implementation, but we modify it slightly so that we can + // print out custom formats for some of our primitives. + pub fn format( + self: Action, + comptime layout: []const u8, + opts: std.fmt.FormatOptions, + writer: anytype, + ) !void { + _ = layout; + 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 this is the active field... + if (self == @field(TagType, u_field.name)) { + const value = @field(self, u_field.name); + switch (@TypeOf(value)) { + // Unicode + u21 => try std.fmt.format(writer, "'{u}'", .{value}), + + // Note: we don't do ASCII (u8) because there are a lot + // of invisible characters we don't want to handle right + // now. + + // All others do the default behavior + else => try std.fmt.formatType( + @field(self, u_field.name), + "any", + opts, + writer, + 3, + ), + } + } + } + + try writer.writeAll(" }"); + } else { + try format(writer, "@{x}", .{@ptrToInt(&self)}); + } + } }; /// Keeps track of the parameter sep used for CSI params. We allow colons diff --git a/src/terminal/stream.zig b/src/terminal/stream.zig index 39b7e9080..9c2b8cd55 100644 --- a/src/terminal/stream.zig +++ b/src/terminal/stream.zig @@ -49,10 +49,7 @@ pub fn Stream(comptime Handler: type) type { const actions = self.parser.next(c); for (actions) |action_opt| { // if (action_opt) |action| { - // switch (action) { - // .print => |p| log.info("action: print '{u}'", .{p}), - // else => log.info("action: {}", .{action}), - // } + // log.info("action: {}", .{action}); // } switch (action_opt orelse continue) { .print => |p| if (@hasDecl(T, "print")) try self.handler.print(p),