mod(style): styling and color revamp now with fewer characters to print to the terminal

This commit is contained in:
2025-02-04 17:51:28 +01:00
parent 2bfacc0e98
commit 9c06ced658
4 changed files with 64 additions and 154 deletions

View File

@@ -22,7 +22,7 @@ pub const Underline = enum {
dashed,
};
pub const Attribute = enum(u32) {
pub const Attribute = enum(u8) {
reset = 0,
bold = 1,
dim,
@@ -34,52 +34,42 @@ pub const Attribute = enum(u32) {
strikethrough,
};
fg: Color = .{ .ansi = .reset },
bg: Color = .{ .ansi = .reset },
ul: Color = .{ .ansi = .reset },
fg: Color = .white,
bg: Color = .default,
ul: Color = .default,
ul_style: Underline = .off,
attributes: []const Attribute,
pub fn eql(this: Style, other: Style) bool {
const ret = this.fg.eql(other.fg) and
this.bg.eql(other.bg) and
this.ul.eql(other.ul) and
other.ul_style == this.ul_style and
other.attributes.len == this.attributes.len;
if (ret == false) return false;
// are the attributes also identical?
for (0..this.attributes.len) |i| {
if (this.attributes[i] != other.attributes[i])
return false;
}
return true;
return std.meta.eql(this, other);
}
pub fn value(this: Style, writer: anytype, cp: u21) !void {
var buffer: [4]u8 = undefined;
const bytes = try std.unicode.utf8Encode(cp, &buffer);
std.debug.assert(bytes > 0);
// start escape sequence
// build ansi sequence for 256 colors ...
// foreground
try std.fmt.format(writer, "\x1b[", .{});
// colors
try this.fg.write(writer, .fg);
// background
try std.fmt.format(writer, ";", .{});
try this.bg.write(writer, .bg);
// try std.fmt.format(writer, ":", .{});
// underline
// try this.ul.write(writer, .ul);
// try std.fmt.format(writer, ":", .{});
// attributes
// FIX: assert that if the underline property is set that the ul style and the attribute for underlining is available
try std.fmt.format(writer, ";", .{});
try this.ul.write(writer, .ul);
// append styles (aka attributes like bold, italic, strikethrough, etc.)
for (this.attributes) |attribute| {
try std.fmt.format(writer, ":{d}", .{@intFromEnum(attribute)});
try std.fmt.format(writer, ";{d}", .{@intFromEnum(attribute)});
}
// end styling
try std.fmt.format(writer, "m", .{});
// content
try std.fmt.format(writer, "{s}", .{buffer});
// end escape sequence
try writer.print("\x1b[0m", .{});
// TODO: is it necessary to reset the graphics mode afterwards to ensure
// that everything rendered behind is still as expected (without any
// side-effects)?
// try writer.print("\x1b[0m", .{});
}
// TODO: implement helper functions for terminal capabilities: