aboutsummaryrefslogtreecommitdiff
path: root/src/ansi.zig
blob: 44f5de601fdfa9b786dcad65d99ab46436cd691d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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");
    }
};