Initial release
This commit is contained in:
parent
84a25cc089
commit
395374409c
10 changed files with 1301 additions and 0 deletions
220
src/ansi-term/style.zig
Normal file
220
src/ansi-term/style.zig
Normal file
|
@ -0,0 +1,220 @@
|
|||
const std = @import("std");
|
||||
const meta = std.meta;
|
||||
const expect = std.testing.expect;
|
||||
const expectEqual = std.testing.expectEqual;
|
||||
|
||||
pub const ColorRGB = struct {
|
||||
r: u8,
|
||||
g: u8,
|
||||
b: u8,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub fn eql(self: Self, other: Self) bool {
|
||||
return meta.eql(self, other);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Color = union(enum) {
|
||||
Default,
|
||||
Black,
|
||||
Red,
|
||||
Green,
|
||||
Yellow,
|
||||
Blue,
|
||||
Magenta,
|
||||
Cyan,
|
||||
White,
|
||||
Fixed: u8,
|
||||
Grey: u8,
|
||||
RGB: ColorRGB,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub fn eql(self: Self, other: Self) bool {
|
||||
return meta.eql(self, other);
|
||||
}
|
||||
};
|
||||
|
||||
pub const FontStyle = packed struct {
|
||||
bold: bool = false,
|
||||
dim: bool = false,
|
||||
italic: bool = false,
|
||||
underline: bool = false,
|
||||
slowblink: bool = false,
|
||||
rapidblink: bool = false,
|
||||
reverse: bool = false,
|
||||
hidden: bool = false,
|
||||
crossedout: bool = false,
|
||||
fraktur: bool = false,
|
||||
overline: bool = false,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub const bold = Self{
|
||||
.bold = true,
|
||||
};
|
||||
|
||||
pub const dim = Self{
|
||||
.dim = true,
|
||||
};
|
||||
|
||||
pub const italic = Self{
|
||||
.italic = true,
|
||||
};
|
||||
|
||||
pub const underline = Self{
|
||||
.underline = true,
|
||||
};
|
||||
|
||||
pub const slowblink = Self{
|
||||
.slowblink = true,
|
||||
};
|
||||
|
||||
pub const rapidblink = Self{
|
||||
.rapidblink = true,
|
||||
};
|
||||
|
||||
pub const reverse = Self{
|
||||
.reverse = true,
|
||||
};
|
||||
|
||||
pub const hidden = Self{
|
||||
.hidden = true,
|
||||
};
|
||||
|
||||
pub const crossedout = Self{
|
||||
.crossedout = true,
|
||||
};
|
||||
|
||||
pub const fraktur = Self{
|
||||
.fraktur = true,
|
||||
};
|
||||
|
||||
pub const overline = Self{
|
||||
.overline = true,
|
||||
};
|
||||
|
||||
pub fn toU11(self: Self) u11 {
|
||||
return @bitCast(self);
|
||||
}
|
||||
|
||||
pub fn fromU11(bits: u11) Self {
|
||||
return @bitCast(bits);
|
||||
}
|
||||
|
||||
/// Returns true iff this font style contains no attributes
|
||||
pub fn isDefault(self: Self) bool {
|
||||
return self.toU11() == 0;
|
||||
}
|
||||
|
||||
/// Returns true iff these font styles contain exactly the same
|
||||
/// attributes
|
||||
pub fn eql(self: Self, other: Self) bool {
|
||||
return self.toU11() == other.toU11();
|
||||
}
|
||||
|
||||
/// Returns true iff self is a subset of the attributes of
|
||||
/// other, i.e. all attributes of self are at least present in
|
||||
/// other as well
|
||||
pub fn subsetOf(self: Self, other: Self) bool {
|
||||
return self.toU11() & other.toU11() == self.toU11();
|
||||
}
|
||||
|
||||
/// Returns this font style with all attributes removed that are
|
||||
/// contained in other
|
||||
pub fn without(self: Self, other: Self) Self {
|
||||
return fromU11(self.toU11() & ~other.toU11());
|
||||
}
|
||||
};
|
||||
|
||||
test "FontStyle bits" {
|
||||
try expectEqual(@as(u11, 0), (FontStyle{}).toU11());
|
||||
try expectEqual(@as(u11, 1), (FontStyle.bold).toU11());
|
||||
try expectEqual(@as(u11, 1 << 2), (FontStyle.italic).toU11());
|
||||
try expectEqual(@as(u11, 1 << 2) | 1, (FontStyle{ .bold = true, .italic = true }).toU11());
|
||||
try expectEqual(FontStyle{}, FontStyle.fromU11((FontStyle{}).toU11()));
|
||||
try expectEqual(FontStyle.bold, FontStyle.fromU11((FontStyle.bold).toU11()));
|
||||
}
|
||||
|
||||
test "FontStyle subsetOf" {
|
||||
const default = FontStyle{};
|
||||
const bold = FontStyle.bold;
|
||||
const italic = FontStyle.italic;
|
||||
const bold_and_italic = FontStyle{ .bold = true, .italic = true };
|
||||
|
||||
try expect(default.subsetOf(default));
|
||||
try expect(default.subsetOf(bold));
|
||||
try expect(bold.subsetOf(bold));
|
||||
try expect(!bold.subsetOf(default));
|
||||
try expect(!bold.subsetOf(italic));
|
||||
try expect(default.subsetOf(bold_and_italic));
|
||||
try expect(bold.subsetOf(bold_and_italic));
|
||||
try expect(italic.subsetOf(bold_and_italic));
|
||||
try expect(bold_and_italic.subsetOf(bold_and_italic));
|
||||
try expect(!bold_and_italic.subsetOf(bold));
|
||||
try expect(!bold_and_italic.subsetOf(italic));
|
||||
try expect(!bold_and_italic.subsetOf(default));
|
||||
}
|
||||
|
||||
test "FontStyle without" {
|
||||
const default = FontStyle{};
|
||||
const bold = FontStyle.bold;
|
||||
const italic = FontStyle.italic;
|
||||
const bold_and_italic = FontStyle{ .bold = true, .italic = true };
|
||||
|
||||
try expectEqual(default, default.without(default));
|
||||
try expectEqual(bold, bold.without(default));
|
||||
try expectEqual(default, bold.without(bold));
|
||||
try expectEqual(bold, bold.without(italic));
|
||||
try expectEqual(bold, bold_and_italic.without(italic));
|
||||
try expectEqual(italic, bold_and_italic.without(bold));
|
||||
try expectEqual(default, bold_and_italic.without(bold_and_italic));
|
||||
}
|
||||
|
||||
pub const Style = struct {
|
||||
foreground: Color = .Default,
|
||||
background: Color = .Default,
|
||||
font_style: FontStyle = FontStyle{},
|
||||
|
||||
const Self = @This();
|
||||
|
||||
/// Returns true iff this style equals the other style in
|
||||
/// foreground color, background color and font style
|
||||
pub fn eql(self: Self, other: Self) bool {
|
||||
if (!self.font_style.eql(other.font_style))
|
||||
return false;
|
||||
|
||||
if (!meta.eql(self.foreground, other.foreground))
|
||||
return false;
|
||||
|
||||
return meta.eql(self.background, other.background);
|
||||
}
|
||||
|
||||
/// Returns true iff this style equals the default set of styles
|
||||
pub fn isDefault(self: Self) bool {
|
||||
return eql(self, Self{});
|
||||
}
|
||||
|
||||
// pub const parse = @import("parse_style.zig").parseStyle;
|
||||
};
|
||||
|
||||
test "style equality" {
|
||||
const a = Style{};
|
||||
const b = Style{
|
||||
.font_style = FontStyle.bold,
|
||||
};
|
||||
const c = Style{
|
||||
.foreground = Color.Red,
|
||||
};
|
||||
|
||||
try expect(a.isDefault());
|
||||
|
||||
try expect(a.eql(a));
|
||||
try expect(b.eql(b));
|
||||
try expect(c.eql(c));
|
||||
|
||||
try expect(!a.eql(b));
|
||||
try expect(!b.eql(a));
|
||||
try expect(!a.eql(c));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue