const std = @import("std"); fn write_csi(writer: anytype, args: anytype, command: u8) !void { try writer.writeAll("\x1b["); inline for (args, 0..) |code, index| { try writer.print("{}", .{code}); if (index < args.len - 1) { try writer.writeByte(';'); } } try writer.writeByte(command); } pub const Color = enum(u8) { const Self = @This(); black = 0, red = 1, green = 2, yellow = 3, blue = 4, magenta = 5, cyan = 6, white = 7, gray = 60, bright_red = 61, bright_green = 62, bright_yellow = 63, bright_blue = 64, bright_magenta = 65, bright_cyan = 66, bright_white = 67, const foreground_offset = 30; const background_offset = 40; pub fn to_fg(self: Self) u8 { return @intFromEnum(self) + foreground_offset; } pub fn to_bg(self: Self) u8 { return @intFromEnum(self) + background_offset; } }; pub const Styled = struct { const Self = @This(); text: []const u8, fg: Color = .white, bg: Color = .black, bold: bool = false, dim: bool = false, italic: bool = false, underline: bool = false, const Codes = struct { const reset = 0; const bold = 1; const dim = 2; const italic = 3; const underline = 4; }; pub fn format( self: *const Self, writer: *std.Io.Writer, ) !void { try write_csi(writer, .{self.fg.to_fg()}, 'm'); try write_csi(writer, .{self.bg.to_bg()}, 'm'); if (self.bold) try write_csi(writer, .{Codes.bold}, 'm'); if (self.dim) try write_csi(writer, .{Codes.dim}, 'm'); if (self.italic) try write_csi(writer, .{Codes.italic}, 'm'); if (self.underline) try write_csi(writer, .{Codes.underline}, 'm'); try writer.writeAll(self.text); try write_csi(writer, .{Codes.reset}, 'm'); } }; pub const ClearLine = struct { pub fn format( self: *const @This(), writer: *std.Io.Writer, ) !void { _ = self; try writer.writeAll("\x1b[2K\r"); } };