diff --git a/src/terminal/Parser.zig b/src/terminal/Parser.zig index 88e7edf7c..34e7e30f4 100644 --- a/src/terminal/Parser.zig +++ b/src/terminal/Parser.zig @@ -166,12 +166,18 @@ pub const Action = union(enum) { // of invisible characters we don't want to handle right // now. - // All others do the default behavior + // All others do the default behavior. Note the max + // depth of 1: this is only used for logging so we + // only want the top-level fields. Larger depths + // instantiate a recursive formatter for every nested + // type of every action payload (e.g. the full + // osc.Command union), which costs tens of kilobytes + // of binary size. else => try writer.printValue( "any", .{}, @field(self, u_field.name), - 3, + 1, ), } } @@ -386,10 +392,7 @@ inline fn doAction(self: *Parser, action: TransitionAction, c: u8) ?Action { // We only allow colon or mixed separators for the 'm' command. if (c != 'm' and self.params_sep.count() > 0) { @branchHint(.cold); - log.warn( - "CSI colon or mixed separators only allowed for 'm' command, got: {f}", - .{result}, - ); + warnCsiSepMismatch(result.csi_dispatch); break :csi_dispatch null; } @@ -406,6 +409,20 @@ inline fn doAction(self: *Parser, action: TransitionAction, c: u8) ?Action { }; } +/// Log a warning for a CSI dispatch with colon/mixed separators on a +/// non-'m' command. +/// +/// This is noinline on purpose so that this unlikely (cold) behavior +/// doesn't bloat the hot dispatch path which has been measured to actually +/// affect both binary size and performance due to icache busts. +noinline fn warnCsiSepMismatch(csi: Action.CSI) void { + @branchHint(.cold); + log.warn( + "CSI colon or mixed separators only allowed for 'm' command, got: {f}", + .{csi}, + ); +} + pub inline fn clear(self: *Parser) void { self.intermediates_idx = 0; self.params_idx = 0;