A pretty printer for zig
zig

customizable color theme

altagos.dev 5c3efbdc 85e44017

verified
+80 -31
+4 -1
example/main.zig
··· 44 print("Boolean false - {f}\n", .{pretty(false)}); 45 print( 46 "Boolean true always with type name - {f}\n", 47 - .{Pretty(bool, .{ .always_show_type_names = true, .type_value_sep = ": " }).init(true)}, 48 ); 49 50 print("\nUnsigned Integers\n", .{});
··· 44 print("Boolean false - {f}\n", .{pretty(false)}); 45 print( 46 "Boolean true always with type name - {f}\n", 47 + .{Pretty(bool, .{ 48 + .always_show_type_names = true, 49 + .theme = .{ .type_value_sep = ": " }, 50 + }).init(true)}, 51 ); 52 53 print("\nUnsigned Integers\n", .{});
+76 -30
pretty.zig
··· 11 show_type_names: bool = true, 12 always_show_type_names: bool = false, 13 14 field_name_type_sep: []const u8 = ": ", 15 type_value_sep: []const u8 = " = ", 16 }; 17 18 const default_options: Options = if (@hasDecl(root, "pretty_options")) root.pretty_options else .{}; ··· 74 return this.out.writeAll(text); 75 } 76 77 - pub inline fn setColor(this: RuntimeContext, color: Io.Terminal.Color) void { 78 this.tty.setColor(color) catch {}; 79 } 80 ··· 113 if (opts.dont_skip_type_name) try printType(T, cctx, rctx); 114 115 return switch (info) { 116 - .bool => formatBool(rctx, value), 117 - .null => formatNull(rctx), 118 - .type => formatType(rctx, value), 119 120 // comptime types 121 .comptime_int, ··· 126 // enum types 127 .@"enum", 128 .enum_literal, 129 - => formatValue(rctx, value), 130 131 .optional => |opt| formatOptional(opt.child, cctx, rctx, value), 132 .@"struct" => |st| formatStruct(T, st, cctx, rctx, value), 133 134 else => { 135 - rctx.setColor(.red); 136 try rctx.print("Unimplemented! ({} = {any})", .{ info, value }); 137 rctx.resetColor(); 138 }, ··· 151 }; 152 153 if ((cctx.depth != 0 or cctx.options.always_show_type_names) and !excluded) { 154 - rctx.setColor(.dim); 155 156 if (cctx.options.show_type_names) { 157 try rctx.write(@typeName(T)); 158 } 159 - try rctx.write(cctx.options.type_value_sep); 160 161 rctx.resetColor(); 162 } 163 } 164 165 - inline fn formatBool(ctx: RuntimeContext, value: bool) !void { 166 - ctx.setColor(if (value) .bright_green else .bright_red); 167 - try ctx.print("{}", .{value}); 168 - ctx.resetColor(); 169 } 170 171 - inline fn formatNull(ctx: RuntimeContext) !void { 172 - ctx.setColor(.cyan); 173 - try ctx.write("null"); 174 - ctx.resetColor(); 175 } 176 177 inline fn formatOptional( ··· 183 return if (value) |val| 184 innerFmt(T, cctx, rctx, val, .{ .dont_skip_type_name = false }) 185 else 186 - formatNull(rctx); 187 } 188 189 inline fn formatStruct( ··· 201 }; 202 203 if (cctx.options.inline_structs) { 204 - rctx.setColor(.dim); 205 try rctx.write(".{ "); 206 rctx.resetColor(); 207 } ··· 211 indent(next_cctx, rctx); 212 if (index != 0 and cctx.options.inline_structs) try rctx.write(", "); 213 214 - rctx.setColor(.green); 215 - try rctx.write("." ++ field.name ++ cctx.options.field_name_type_sep); 216 rctx.resetColor(); 217 218 try innerFmt(field.type, next_cctx, rctx, @field(value, field.name), .{}); ··· 221 } 222 223 if (cctx.options.inline_structs) { 224 - rctx.setColor(.dim); 225 try rctx.write(" }"); 226 rctx.resetColor(); 227 } 228 } 229 230 - inline fn formatType(ctx: RuntimeContext, value: type) !void { 231 - ctx.setColor(.bright_blue); 232 - ctx.setColor(.bold); 233 - try ctx.write(@typeName(value)); 234 - ctx.resetColor(); 235 } 236 237 - inline fn formatValue(ctx: RuntimeContext, value: anytype) !void { 238 - ctx.setColor(.blue); 239 - try ctx.print("{}", .{value}); 240 - ctx.resetColor(); 241 } 242 243 inline fn indent(comptime cctx: ComptimeContext, rctx: RuntimeContext) void {
··· 11 show_type_names: bool = true, 12 always_show_type_names: bool = false, 13 14 + theme: Theme = .{}, 15 + }; 16 + 17 + pub const Theme = struct { 18 + pub const Colors = enum { 19 + dim, 20 + field, 21 + value, 22 + @"error", 23 + type, 24 + null, 25 + true, 26 + false, 27 + }; 28 + 29 field_name_type_sep: []const u8 = ": ", 30 type_value_sep: []const u8 = " = ", 31 + 32 + color_dim: Io.Terminal.Color = .dim, 33 + color_field: Io.Terminal.Color = .green, 34 + color_value: Io.Terminal.Color = .blue, 35 + color_error: Io.Terminal.Color = .red, 36 + color_type: Io.Terminal.Color = .bright_blue, 37 + color_null: Io.Terminal.Color = .cyan, 38 + color_true: Io.Terminal.Color = .bright_green, 39 + color_false: Io.Terminal.Color = .bright_red, 40 + 41 + pub fn getColor(this: Theme, option: Colors) Io.Terminal.Color { 42 + return switch (option) { 43 + // .dim => this.color_dim, 44 + // .field => this.color_field, 45 + // .value => this.color_value, 46 + // .@"error" => this.color_error, 47 + // .type => this.color_type, 48 + // .null => this.color_null, 49 + // .true => this.color_true, 50 + // .false => this.color_false, 51 + inline else => |opt| @field(this, "color_" ++ @tagName(opt)), 52 + }; 53 + } 54 }; 55 56 const default_options: Options = if (@hasDecl(root, "pretty_options")) root.pretty_options else .{}; ··· 112 return this.out.writeAll(text); 113 } 114 115 + pub inline fn setColor( 116 + this: RuntimeContext, 117 + comptime ctx: ComptimeContext, 118 + color: Theme.Colors, 119 + ) void { 120 + this.tty.setColor(ctx.options.theme.getColor(color)) catch {}; 121 + } 122 + 123 + pub inline fn setColorRaw(this: RuntimeContext, color: Io.Terminal.Color) void { 124 this.tty.setColor(color) catch {}; 125 } 126 ··· 159 if (opts.dont_skip_type_name) try printType(T, cctx, rctx); 160 161 return switch (info) { 162 + .bool => formatBool(cctx, rctx, value), 163 + .null => formatNull(cctx, rctx), 164 + .type => formatType(cctx, rctx, value), 165 166 // comptime types 167 .comptime_int, ··· 172 // enum types 173 .@"enum", 174 .enum_literal, 175 + => formatValue(cctx, rctx, value), 176 177 .optional => |opt| formatOptional(opt.child, cctx, rctx, value), 178 .@"struct" => |st| formatStruct(T, st, cctx, rctx, value), 179 180 else => { 181 + rctx.setColor(cctx, .@"error"); 182 try rctx.print("Unimplemented! ({} = {any})", .{ info, value }); 183 rctx.resetColor(); 184 }, ··· 197 }; 198 199 if ((cctx.depth != 0 or cctx.options.always_show_type_names) and !excluded) { 200 + rctx.setColor(cctx, .dim); 201 202 if (cctx.options.show_type_names) { 203 try rctx.write(@typeName(T)); 204 } 205 + try rctx.write(cctx.options.theme.type_value_sep); 206 207 rctx.resetColor(); 208 } 209 } 210 211 + inline fn formatBool(comptime cctx: ComptimeContext, rctx: RuntimeContext, value: bool) !void { 212 + rctx.setColor(cctx, if (value) .true else .false); 213 + try rctx.print("{}", .{value}); 214 + rctx.resetColor(); 215 } 216 217 + inline fn formatNull(comptime cctx: ComptimeContext, rctx: RuntimeContext) !void { 218 + rctx.setColor(cctx, .null); 219 + try rctx.write("null"); 220 + rctx.resetColor(); 221 } 222 223 inline fn formatOptional( ··· 229 return if (value) |val| 230 innerFmt(T, cctx, rctx, val, .{ .dont_skip_type_name = false }) 231 else 232 + formatNull(cctx, rctx); 233 } 234 235 inline fn formatStruct( ··· 247 }; 248 249 if (cctx.options.inline_structs) { 250 + rctx.setColor(cctx, .dim); 251 try rctx.write(".{ "); 252 rctx.resetColor(); 253 } ··· 257 indent(next_cctx, rctx); 258 if (index != 0 and cctx.options.inline_structs) try rctx.write(", "); 259 260 + rctx.setColor(cctx, .field); 261 + try rctx.write("." ++ field.name ++ cctx.options.theme.field_name_type_sep); 262 rctx.resetColor(); 263 264 try innerFmt(field.type, next_cctx, rctx, @field(value, field.name), .{}); ··· 267 } 268 269 if (cctx.options.inline_structs) { 270 + rctx.setColor(cctx, .dim); 271 try rctx.write(" }"); 272 rctx.resetColor(); 273 } 274 } 275 276 + inline fn formatType(comptime cctx: ComptimeContext, rctx: RuntimeContext, value: type) !void { 277 + rctx.setColor(cctx, .type); 278 + rctx.setColorRaw(.bold); 279 + try rctx.write(@typeName(value)); 280 + rctx.resetColor(); 281 } 282 283 + inline fn formatValue(comptime cctx: ComptimeContext, rctx: RuntimeContext, value: anytype) !void { 284 + rctx.setColor(cctx, .value); 285 + try rctx.print("{}", .{value}); 286 + rctx.resetColor(); 287 } 288 289 inline fn indent(comptime cctx: ComptimeContext, rctx: RuntimeContext) void {