From 09ee06269d9c939424b2dd6342d286f3c7e08e03 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Mon, 25 Mar 2024 19:54:45 +0100 Subject: [PATCH] build: unvendor ansi-term --- build.zig | 2 + build.zig.zon | 4 + src/ansi-term.zig | 2 - src/ansi-term/format.zig | 304 --------------------------------------- src/ansi-term/style.zig | 220 ---------------------------- src/main.zig | 2 +- 6 files changed, 7 insertions(+), 527 deletions(-) delete mode 100644 src/ansi-term.zig delete mode 100644 src/ansi-term/format.zig delete mode 100644 src/ansi-term/style.zig diff --git a/build.zig b/build.zig index 3dd6c73..63678cc 100644 --- a/build.zig +++ b/build.zig @@ -5,6 +5,7 @@ pub fn build(b: *std.Build) void { const optimize = b.standardOptimizeOption(.{}); const clap_dep = b.dependency("clap", .{ .target = target, .optimize = optimize }); + const ansi_term_dep = b.dependency("ansi-term", .{ .target = target, .optimize = optimize }); const themes_dep = b.dependency("themes", .{}); const syntax_dep = b.dependency("syntax", .{ .target = target, .optimize = optimize }); const thespian_dep = b.dependency("thespian", .{}); @@ -19,6 +20,7 @@ pub fn build(b: *std.Build) void { exe.root_module.addImport("theme", themes_dep.module("theme")); exe.root_module.addImport("themes", themes_dep.module("themes")); exe.root_module.addImport("clap", clap_dep.module("clap")); + exe.root_module.addImport("ansi-term", ansi_term_dep.module("ansi-term")); exe.root_module.addImport("cbor", b.createModule(.{ .root_source_file = thespian_dep.path("src/cbor.zig") })); b.installArtifact(exe); diff --git a/build.zig.zon b/build.zig.zon index 7fbc29c..46799c2 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -18,6 +18,10 @@ .url = "https://github.com/neurocyte/thespian/archive/d20e071a4d50b92bce196040b151988f96985c87.tar.gz", .hash = "12209e9d22ddb9ef7ff18e8781234fbb149c297cf23dda366269b0bbee437a2b8f32", }, + .@"ansi-term" = .{ + .url = "https://github.com/ziglibs/ansi-term/archive/ed0f6c223539c187ba1b54c5cf0cc3b11104188f.tar.gz", + .hash = "12200297afdfc2babebdba3b4950ef8a478fd4cf7aea3354644d348739270580afe9", + }, }, .paths = .{ "build.zig", diff --git a/src/ansi-term.zig b/src/ansi-term.zig deleted file mode 100644 index c9daf05..0000000 --- a/src/ansi-term.zig +++ /dev/null @@ -1,2 +0,0 @@ -pub const style = @import("ansi-term/style.zig"); -pub const format = @import("ansi-term/format.zig"); diff --git a/src/ansi-term/format.zig b/src/ansi-term/format.zig deleted file mode 100644 index e11e032..0000000 --- a/src/ansi-term/format.zig +++ /dev/null @@ -1,304 +0,0 @@ -const std = @import("std"); -const fixedBufferStream = std.io.fixedBufferStream; -const testing = std.testing; - -const style = @import("style.zig"); -const Style = style.Style; -const FontStyle = style.FontStyle; -const Color = style.Color; - -const esc = "\x1B"; -const csi = esc ++ "["; - -const reset = csi ++ "0m"; - -const font_style_codes = std.ComptimeStringMap([]const u8, .{ - .{ "bold", "1" }, - .{ "dim", "2" }, - .{ "italic", "3" }, - .{ "underline", "4" }, - .{ "slowblink", "5" }, - .{ "rapidblink", "6" }, - .{ "reverse", "7" }, - .{ "hidden", "8" }, - .{ "crossedout", "9" }, - .{ "fraktur", "20" }, - .{ "overline", "53" }, -}); - -/// Update the current style of the ANSI terminal -/// -/// Optionally accepts the previous style active on the -/// terminal. Using this information, the function will update only -/// the attributes which are new in order to minimize the amount -/// written. -/// -/// Tries to use as little bytes as necessary. Use this function if -/// you want to optimize for smallest amount of transmitted bytes -/// instead of computation speed. -pub fn updateStyle(writer: anytype, new: Style, old: ?Style) !void { - if (old) |sty| if (new.eql(sty)) return; - if (new.isDefault()) return try resetStyle(writer); - - // A reset is required if the new font style has attributes not - // present in the old style or if the old style is not known - const reset_required = if (old) |sty| !sty.font_style.subsetOf(new.font_style) else true; - if (reset_required) try resetStyle(writer); - - // Start the escape sequence - try writer.writeAll(csi); - var written_something = false; - - // Font styles - const write_styles = if (reset_required) new.font_style else new.font_style.without(old.?.font_style); - inline for (std.meta.fields(FontStyle)) |field| { - if (@field(write_styles, field.name)) { - const code = font_style_codes.get(field.name).?; - if (written_something) { - try writer.writeAll(";"); - } else { - written_something = true; - } - try writer.writeAll(code); - } - } - - // Foreground color - if (reset_required and new.foreground != .Default or old != null and !old.?.foreground.eql(new.foreground)) { - if (written_something) { - try writer.writeAll(";"); - } else { - written_something = true; - } - - switch (new.foreground) { - .Default => try writer.writeAll("39"), - .Black => try writer.writeAll("30"), - .Red => try writer.writeAll("31"), - .Green => try writer.writeAll("32"), - .Yellow => try writer.writeAll("33"), - .Blue => try writer.writeAll("34"), - .Magenta => try writer.writeAll("35"), - .Cyan => try writer.writeAll("36"), - .White => try writer.writeAll("37"), - .Fixed => |fixed| try writer.print("38;5;{}", .{fixed}), - .Grey => |grey| try writer.print("38;2;{};{};{}", .{ grey, grey, grey }), - .RGB => |rgb| try writer.print("38;2;{};{};{}", .{ rgb.r, rgb.g, rgb.b }), - } - } - - // Background color - if (reset_required and new.background != .Default or old != null and !old.?.background.eql(new.background)) { - if (written_something) { - try writer.writeAll(";"); - } else { - written_something = true; - } - - switch (new.background) { - .Default => try writer.writeAll("49"), - .Black => try writer.writeAll("40"), - .Red => try writer.writeAll("41"), - .Green => try writer.writeAll("42"), - .Yellow => try writer.writeAll("43"), - .Blue => try writer.writeAll("44"), - .Magenta => try writer.writeAll("45"), - .Cyan => try writer.writeAll("46"), - .White => try writer.writeAll("47"), - .Fixed => |fixed| try writer.print("48;5;{}", .{fixed}), - .Grey => |grey| try writer.print("48;2;{};{};{}", .{ grey, grey, grey }), - .RGB => |rgb| try writer.print("48;2;{};{};{}", .{ rgb.r, rgb.g, rgb.b }), - } - } - - // End the escape sequence - try writer.writeAll("m"); -} - -test "same style default, no update" { - var buf: [1024]u8 = undefined; - var fixed_buf_stream = fixedBufferStream(&buf); - - try updateStyle(fixed_buf_stream.writer(), Style{}, Style{}); - - const expected = ""; - const actual = fixed_buf_stream.getWritten(); - - try testing.expectEqualSlices(u8, expected, actual); -} - -test "same style non-default, no update" { - var buf: [1024]u8 = undefined; - var fixed_buf_stream = fixedBufferStream(&buf); - - const sty = Style{ - .foreground = Color.Green, - }; - try updateStyle(fixed_buf_stream.writer(), sty, sty); - - const expected = ""; - const actual = fixed_buf_stream.getWritten(); - - try testing.expectEqualSlices(u8, expected, actual); -} - -test "reset to default, old null" { - var buf: [1024]u8 = undefined; - var fixed_buf_stream = fixedBufferStream(&buf); - - try updateStyle(fixed_buf_stream.writer(), Style{}, null); - - const expected = "\x1B[0m"; - const actual = fixed_buf_stream.getWritten(); - - try testing.expectEqualSlices(u8, expected, actual); -} - -test "reset to default, old non-null" { - var buf: [1024]u8 = undefined; - var fixed_buf_stream = fixedBufferStream(&buf); - - try updateStyle(fixed_buf_stream.writer(), Style{}, Style{ - .font_style = FontStyle.bold, - }); - - const expected = "\x1B[0m"; - const actual = fixed_buf_stream.getWritten(); - - try testing.expectEqualSlices(u8, expected, actual); -} - -test "bold style" { - var buf: [1024]u8 = undefined; - var fixed_buf_stream = fixedBufferStream(&buf); - - try updateStyle(fixed_buf_stream.writer(), Style{ - .font_style = FontStyle.bold, - }, Style{}); - - const expected = "\x1B[1m"; - const actual = fixed_buf_stream.getWritten(); - - try testing.expectEqualSlices(u8, expected, actual); -} - -test "add bold style" { - var buf: [1024]u8 = undefined; - var fixed_buf_stream = fixedBufferStream(&buf); - - try updateStyle(fixed_buf_stream.writer(), Style{ - .font_style = FontStyle{ .bold = true, .italic = true }, - }, Style{ - .font_style = FontStyle.italic, - }); - - const expected = "\x1B[1m"; - const actual = fixed_buf_stream.getWritten(); - - try testing.expectEqualSlices(u8, expected, actual); -} - -test "reset required font style" { - var buf: [1024]u8 = undefined; - var fixed_buf_stream = fixedBufferStream(&buf); - - try updateStyle(fixed_buf_stream.writer(), Style{ - .font_style = FontStyle.bold, - }, Style{ - .font_style = FontStyle{ .bold = true, .underline = true }, - }); - - const expected = "\x1B[0m\x1B[1m"; - const actual = fixed_buf_stream.getWritten(); - - try testing.expectEqualSlices(u8, expected, actual); -} - -test "reset required color style" { - var buf: [1024]u8 = undefined; - var fixed_buf_stream = fixedBufferStream(&buf); - - try updateStyle(fixed_buf_stream.writer(), Style{ - .foreground = Color.Red, - }, null); - - const expected = "\x1B[0m\x1B[31m"; - const actual = fixed_buf_stream.getWritten(); - - try testing.expectEqualSlices(u8, expected, actual); -} - -test "no reset required color style" { - var buf: [1024]u8 = undefined; - var fixed_buf_stream = fixedBufferStream(&buf); - - try updateStyle(fixed_buf_stream.writer(), Style{ - .foreground = Color.Red, - }, Style{}); - - const expected = "\x1B[31m"; - const actual = fixed_buf_stream.getWritten(); - - try testing.expectEqualSlices(u8, expected, actual); -} - -test "no reset required add color style" { - var buf: [1024]u8 = undefined; - var fixed_buf_stream = fixedBufferStream(&buf); - - try updateStyle(fixed_buf_stream.writer(), Style{ - .foreground = Color.Red, - .background = Color.Magenta, - }, Style{ - .background = Color.Magenta, - }); - - const expected = "\x1B[31m"; - const actual = fixed_buf_stream.getWritten(); - - try testing.expectEqualSlices(u8, expected, actual); -} - -pub fn resetStyle(writer: anytype) !void { - try writer.writeAll(reset); -} - -test "reset style" { - var buf: [1024]u8 = undefined; - var fixed_buf_stream = fixedBufferStream(&buf); - - try resetStyle(fixed_buf_stream.writer()); - - const expected = "\x1B[0m"; - const actual = fixed_buf_stream.getWritten(); - - try testing.expectEqualSlices(u8, expected, actual); -} - -test "Grey foreground color" { - var buf: [1024]u8 = undefined; - var fixed_buf_stream = fixedBufferStream(&buf); - var new_style = Style{}; - new_style.foreground = Color{ .Grey = 1 }; - - try updateStyle(fixed_buf_stream.writer(), new_style, Style{}); - - const expected = "\x1B[38;2;1;1;1m"; - const actual = fixed_buf_stream.getWritten(); - - try testing.expectEqualSlices(u8, expected, actual); -} - -test "Grey background color" { - var buf: [1024]u8 = undefined; - var fixed_buf_stream = fixedBufferStream(&buf); - var new_style = Style{}; - new_style.background = Color{ .Grey = 1 }; - - try updateStyle(fixed_buf_stream.writer(), new_style, Style{}); - - const expected = "\x1B[48;2;1;1;1m"; - const actual = fixed_buf_stream.getWritten(); - - try testing.expectEqualSlices(u8, expected, actual); -} diff --git a/src/ansi-term/style.zig b/src/ansi-term/style.zig deleted file mode 100644 index a759273..0000000 --- a/src/ansi-term/style.zig +++ /dev/null @@ -1,220 +0,0 @@ -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)); -} diff --git a/src/main.zig b/src/main.zig index fea0358..141061a 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3,7 +3,7 @@ const clap = @import("clap"); const syntax = @import("syntax"); const Theme = @import("theme"); const themes = @import("themes"); -const term = @import("ansi-term.zig"); +const term = @import("ansi-term"); const config_loader = @import("config_loader.zig"); const Writer = std.io.BufferedWriter(4096, std.fs.File.Writer).Writer;