From cea262e0660ba303ef3d8cae04df5ad96901be2e Mon Sep 17 00:00:00 2001 From: rhues <4503559+rhues@users.noreply.github.com> Date: Tue, 4 Jun 2024 08:17:14 -0700 Subject: [PATCH] Fixed issue 52 by using only native Windows colors on Windows. This should fix log colorization for all Windows terminals. Note: when Zig 0.12 support is no longer needed, a much more elegant solution is possible that allows ANSI colors on Windows. This fix works with Zig 0.12 and up. --- src/jetzig/colors.zig | 95 ++++++++++++++++++--------------- src/jetzig/loggers/LogQueue.zig | 21 ++++---- 2 files changed, 62 insertions(+), 54 deletions(-) diff --git a/src/jetzig/colors.zig b/src/jetzig/colors.zig index d7fa039..032b3e3 100644 --- a/src/jetzig/colors.zig +++ b/src/jetzig/colors.zig @@ -31,50 +31,61 @@ pub const codes = .{ /// Map color codes generated by `std.io.tty.Config.setColor` back to `std.io.tty.Color`. Used by /// `jetzig.loggers.LogQueue.writeWindows` to parse escape codes so they can be passed to /// `std.io.tty.Config.setColor` (using Windows API to set console color mode). +const ansi_colors = .{ + .{ "30", .black }, + .{ "31", .red }, + .{ "32", .green }, + .{ "33", .yellow }, + .{ "34", .blue }, + .{ "35", .magenta }, + .{ "36", .cyan }, + .{ "37", .white }, + .{ "90", .bright_black }, + .{ "91", .bright_red }, + .{ "92", .bright_green }, + .{ "93", .bright_yellow }, + .{ "94", .bright_blue }, + .{ "95", .bright_magenta }, + .{ "96", .bright_cyan }, + .{ "97", .bright_white }, + .{ "1", .bold }, + .{ "2", .dim }, + .{ "0", .reset }, +}; pub const codes_map = if (@hasDecl(std, "ComptimeStringMap")) - std.ComptimeStringMap(std.io.tty.Color, .{ - .{ "30", .black }, - .{ "31", .red }, - .{ "32", .green }, - .{ "33", .yellow }, - .{ "34", .blue }, - .{ "35", .magenta }, - .{ "36", .cyan }, - .{ "37", .white }, - .{ "90", .bright_black }, - .{ "91", .bright_red }, - .{ "92", .bright_green }, - .{ "93", .bright_yellow }, - .{ "94", .bright_blue }, - .{ "95", .bright_magenta }, - .{ "96", .bright_cyan }, - .{ "97", .bright_white }, - .{ "1", .bold }, - .{ "2", .dim }, - .{ "0", .reset }, - }) + std.ComptimeStringMap(std.io.tty.Color, ansi_colors) else if (@hasDecl(std, "StaticStringMap")) - std.StaticStringMap(std.io.tty.Color).initComptime(.{ - .{ "30", .black }, - .{ "31", .red }, - .{ "32", .green }, - .{ "33", .yellow }, - .{ "34", .blue }, - .{ "35", .magenta }, - .{ "36", .cyan }, - .{ "37", .white }, - .{ "90", .bright_black }, - .{ "91", .bright_red }, - .{ "92", .bright_green }, - .{ "93", .bright_yellow }, - .{ "94", .bright_blue }, - .{ "95", .bright_magenta }, - .{ "96", .bright_cyan }, - .{ "97", .bright_white }, - .{ "1", .bold }, - .{ "2", .dim }, - .{ "0", .reset }, - }) + std.StaticStringMap(std.io.tty.Color).initComptime(ansi_colors) +else + unreachable; + +// Map basic ANSI color codes to Windows TextAttribute colors +// used by std.os.windows.SetConsoleTextAttribute() +const windows_colors = .{ + .{ "30", 0 }, + .{ "31", 4 }, + .{ "32", 2 }, + .{ "33", 6 }, + .{ "34", 1 }, + .{ "35", 5 }, + .{ "36", 3 }, + .{ "37", 7 }, + .{ "90", 8 }, + .{ "91", 12 }, + .{ "92", 10 }, + .{ "93", 14 }, + .{ "94", 9 }, + .{ "95", 13 }, + .{ "96", 11 }, + .{ "97", 15 }, + .{ "1", 7 }, + .{ "2", 7 }, + .{ "0", 7 }, +}; +pub const windows_map = if (@hasDecl(std, "ComptimeStringMap")) + std.ComptimeStringMap(u16, windows_colors) +else if (@hasDecl(std, "StaticStringMap")) + std.StaticStringMap(u16).initComptime(windows_colors) else unreachable; diff --git a/src/jetzig/loggers/LogQueue.zig b/src/jetzig/loggers/LogQueue.zig index b49edd6..26a9e95 100644 --- a/src/jetzig/loggers/LogQueue.zig +++ b/src/jetzig/loggers/LogQueue.zig @@ -273,23 +273,20 @@ fn initPool(allocator: std.mem.Allocator, T: type) std.heap.MemoryPool(T) { fn writeWindows(file: std.fs.File, writer: anytype, event: Event) !void { var info: std.os.windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; - const config: std.io.tty.Config = if (std.os.windows.kernel32.GetConsoleScreenBufferInfo( - file.handle, - &info, - ) != std.os.windows.TRUE) - .no_color - else - .{ .windows_api = .{ - .handle = file.handle, - .reset_attributes = info.wAttributes, - } }; + _ = std.os.windows.kernel32.GetConsoleScreenBufferInfo( + file.handle, + &info + ); var it = std.mem.tokenizeSequence(u8, event.message[0..event.len], "\x1b["); while (it.next()) |token| { if (std.mem.indexOfScalar(u8, token, 'm')) |index| { if (index > 0 and index + 1 < token.len) { - if (jetzig.colors.codes_map.get(token[0..index])) |color| { - try config.setColor(writer, color); + if (jetzig.colors.windows_map.get(token[0..index])) |color| { + try std.os.windows.SetConsoleTextAttribute( + file.handle, + color + ); try writer.writeAll(token[index + 1 ..]); continue; }