diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8765f77..729492e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v2 - uses: goto-bus-stop/setup-zig@v1 with: - version: 0.15.2 + version: 0.16.0 - name: Install uv uses: astral-sh/setup-uv@v6 with: @@ -33,7 +33,7 @@ jobs: - uses: actions/checkout@v2 - uses: goto-bus-stop/setup-zig@v1 with: - version: 0.15.2 + version: 0.16.0 - run: zig fmt --check . - name: Install uv uses: astral-sh/setup-uv@v6 diff --git a/README.md b/README.md index 2bc49c0..069add8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ![CI](https://github.com/tammoippen/zig-plotille/actions/workflows/main.yml/badge.svg) -[![zig 0.15.2](https://img.shields.io/badge/Zig-0.15.2-color?logo=zig&color=%23f3ab20)](https://ziglang.org/download/0.15.1/release-notes.html) +[![zig 0.16.0](https://img.shields.io/badge/Zig-0.16.0-color?logo=zig&color=%23f3ab20)](https://ziglang.org/download/0.16.0/release-notes.html) # zig-plotille @@ -81,10 +81,13 @@ Display all available named colors in a grid: ```zig const plt = @import("plotille"); +// Zig 0.16 hands I/O and the environment to `main` via `std.process.Init`: +// pub fn main(init: std.process.Init) !void { ... } + // Detect terminal capabilities // ALWAYS required, before printing with color support // (either set or detect) -try plt.terminfo.TermInfo.detect(allocator); +try plt.terminfo.TermInfo.detect(init.io, init.minimal.environ, allocator); // Display color grid for (std.enums.values(plt.color.ColorName)) |bg_value| { diff --git a/build.zig b/build.zig index cc0747a..526f96c 100644 --- a/build.zig +++ b/build.zig @@ -17,7 +17,7 @@ pub fn build(b: *std.Build) !void { const name = "plotille"; const entry = b.path("src/main.zig"); - const version = try std.SemanticVersion.parse("0.0.1"); + const version = try std.SemanticVersion.parse("0.1.0"); const module = b.addModule(name, .{ .root_source_file = entry, .target = target, @@ -32,6 +32,7 @@ pub fn build(b: *std.Build) !void { .target = target, .optimize = mode, .strip = strip, + .link_libc = true, }); const static_lib = b.addLibrary(.{ .name = name, @@ -39,7 +40,6 @@ pub fn build(b: *std.Build) !void { .version = version, .linkage = .static, }); - static_lib.linkLibC(); const installed_static_lib = b.addInstallArtifact(static_lib, .{}); b.getInstallStep().dependOn(&installed_static_lib.step); @@ -50,7 +50,6 @@ pub fn build(b: *std.Build) !void { .version = version, .linkage = .dynamic, }); - shared_lib.linkLibC(); const installed_shared_lib = b.addInstallArtifact(shared_lib, .{}); b.getInstallStep().dependOn(&installed_shared_lib.step); diff --git a/build.zig.zon b/build.zig.zon index 7689327..58b632c 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,7 +1,7 @@ .{ .name = .plotille, - .version = "0.0.1", - .minimum_zig_version = "0.15.2", + .version = "0.1.0", + .minimum_zig_version = "0.16.0", .dependencies = .{}, .paths = .{ "src", diff --git a/src/c-api.zig b/src/c-api.zig index 705f51b..6513074 100644 --- a/src/c-api.zig +++ b/src/c-api.zig @@ -15,11 +15,11 @@ export fn dots_init() dots.Dots { return dots.Dots{}; } export fn dots_str(self: dots.Dots, buf: [*]u8, len: usize) usize { - var fbs = std.io.fixedBufferStream(buf[0..len]); - std.fmt.format(fbs.writer(), "{f}", .{self}) catch |err| switch (err) { - error.NoSpaceLeft => return 0, + var w: std.Io.Writer = .fixed(buf[0..len]); + w.print("{f}", .{self}) catch |err| switch (err) { + error.WriteFailed => return 0, }; - return fbs.pos; + return w.end; } export fn dots_fill(self: *dots.Dots) void { return self.fill(); @@ -57,23 +57,33 @@ export fn color_by_hsl(h: f64, s: f64, l: f64) color.Color { } export fn color_str(buf: [*]u8, len: usize, text: [*:0]const u8, options: color.ColorOptions) usize { - var fbs = std.io.fixedBufferStream(buf[0..len]); - color.colorPrint(fbs.writer(), "{s}", .{text}, options) catch return 0; - return fbs.pos; + var w: std.Io.Writer = .fixed(buf[0..len]); + color.colorPrint(&w, "{s}", .{text}, options) catch return 0; + return w.end; } // terminfo +/// The environment block of the process. A C caller does not hand us a +/// `std.process.Init`, so pick it up from libc (which this library links). +fn processEnviron() std.process.Environ { + if (@import("builtin").os.tag == .windows) return .{ .block = .global }; + const c_environ = std.c.environ; + var count: usize = 0; + while (c_environ[count] != null) : (count += 1) {} + return .{ .block = .{ .slice = c_environ[0..count :null] } }; +} + export fn get_terminfo(out: *terminfo.TermInfo) bool { if (terminfo.TermInfo.is_set()) { out.* = terminfo.TermInfo.get(); return true; } - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - defer _ = gpa.deinit(); - const allocator = gpa.allocator(); + const allocator = std.heap.c_allocator; + // no `std.process.Init` available from C, so use the hardcoded instance + const io = std.Io.Threaded.global_single_threaded.io(); - terminfo.TermInfo.detect(allocator) catch return false; + terminfo.TermInfo.detect(io, processEnviron(), allocator) catch return false; out.* = terminfo.TermInfo.get(); return true; } @@ -127,9 +137,9 @@ export fn hist_free(h: *CHistogram) void { export fn hist_str(h: CHistogram, buf: [*]u8, len: usize) usize { if (h._internal) |internal| { const hist_ptr: *const hist.Histogram = @ptrCast(@alignCast(internal)); - var fbs = std.io.fixedBufferStream(buf[0..len]); - std.fmt.format(fbs.writer(), "{f}", .{hist_ptr.*}) catch return 0; - return fbs.pos; + var w: std.Io.Writer = .fixed(buf[0..len]); + w.print("{f}", .{hist_ptr.*}) catch return 0; + return w.end; } return 0; } @@ -246,9 +256,9 @@ export fn canvas_text(c: *CCanvas, p: canvas.Point, text: [*:0]const u8, fg_colo export fn canvas_str(c: CCanvas, buf: [*]u8, len: usize) usize { if (c._internal) |internal| { const canvas_ptr: *const canvas.Canvas = @ptrCast(@alignCast(internal)); - var fbs = std.io.fixedBufferStream(buf[0..len]); - std.fmt.format(fbs.writer(), "{f}", .{canvas_ptr.*}) catch return 0; - return fbs.pos; + var w: std.Io.Writer = .fixed(buf[0..len]); + w.print("{f}", .{canvas_ptr.*}) catch return 0; + return w.end; } return 0; } @@ -460,9 +470,9 @@ export fn figure_prepare(f: *CFigure) bool { export fn figure_str(f: CFigure, buf: [*]u8, len: usize) usize { if (f._internal) |internal| { const figure_ptr: *const figure.Figure = @ptrCast(@alignCast(internal)); - var fbs = std.io.fixedBufferStream(buf[0..len]); - std.fmt.format(fbs.writer(), "{f}", .{figure_ptr.*}) catch return 0; - return fbs.pos; + var w: std.Io.Writer = .fixed(buf[0..len]); + w.print("{f}", .{figure_ptr.*}) catch return 0; + return w.end; } return 0; } diff --git a/src/canvas.zig b/src/canvas.zig index 025d446..33f680d 100644 --- a/src/canvas.zig +++ b/src/canvas.zig @@ -480,7 +480,7 @@ test "simple format canvas" { var c = try Canvas.init(std.testing.allocator, 10, 10, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); c.point(.{ .x = 0, .y = 0 }, null, null); @@ -494,7 +494,7 @@ test "simple format canvas" { c.point(.{ .x = 0.5, .y = 0 }, null, null); c.point(.{ .x = 0.5, .y = 0.5 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠁⠀⠀⠀⠀⠁⠀⠀⠀⠀ \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ @@ -513,7 +513,7 @@ test "points with chars in canvas" { var c = try Canvas.init(std.testing.allocator, 10, 10, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); c.point(.{ .x = 0, .y = 0 }, null, 'x'); @@ -527,7 +527,7 @@ test "points with chars in canvas" { c.point(.{ .x = 0.5, .y = 0 }, null, 'v'); c.point(.{ .x = 0.5, .y = 0.5 }, null, 'b'); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\z⠀⠀⠀⠀u⠀⠀⠀⠀ \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ @@ -549,7 +549,7 @@ test "format canvas with color" { var c = try Canvas.init(std.testing.allocator, 10, 10, color.Color.by_name(.bright_yellow)); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); c.point(.{ .x = 0, .y = 0 }, color.Color.by_name(.red), null); @@ -563,7 +563,7 @@ test "format canvas with color" { c.point(.{ .x = 0.5, .y = 0 }, color.Color.by_name(.black), null); c.point(.{ .x = 0.5, .y = 0.5 }, color.Color.by_name(.blue), null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStrings("\x1b[30;103m⠁\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[30;103m⠁\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m" ++ utils.line_separator ++ "\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m" ++ utils.line_separator ++ "\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m" ++ utils.line_separator ++ @@ -580,12 +580,12 @@ test "fill char in canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); c.fillChar(.{ .x = 0.5, .y = 0.5 }); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⣿⠀ @@ -597,12 +597,12 @@ test "line in canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0, .y = 0 }, .{ .x = 0.99, .y = 0.99 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⡜ \\⠀⡜⠀ @@ -614,12 +614,12 @@ test "line in canvas with chars" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0, .y = 0 }, .{ .x = 0.99, .y = 0.99 }, null, 'X'); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀X \\⠀⡜⠀ @@ -631,12 +631,12 @@ test "line in one point in canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0.5, .y = 0.5 }, .{ .x = 0.6, .y = 0.55 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠐⠀ @@ -648,7 +648,7 @@ test "point out of canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); c.point(.{ .x = -1, .y = -1 }, null, null); @@ -661,7 +661,7 @@ test "point out of canvas" { c.point(.{ .x = -0.1, .y = -0.02 }, null, null); c.point(.{ .x = 1, .y = 1 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠀⠀ @@ -673,12 +673,12 @@ test "horizontal line out of canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.line(.{ .x = -0.99, .y = 0.5 }, .{ .x = 2, .y = 0.5 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠒⠒⠒ @@ -690,12 +690,12 @@ test "vertical line out of canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0.5, .y = -0.99 }, .{ .x = 0.5, .y = 2 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⢸⠀ \\⠀⢸⠀ @@ -707,12 +707,12 @@ test "line out of canvas reversed" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.line(.{ .x = 2, .y = 0.5 }, .{ .x = -0.99, .y = 0.5 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠒⠒⠒ @@ -724,12 +724,12 @@ test "vertical line out of canvas reversed" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0.5, .y = 2 }, .{ .x = 0.5, .y = -0.99 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⢸⠀ \\⠀⢸⠀ @@ -741,12 +741,12 @@ test "line in canvas small y" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0.5, .y = 0.5 }, .{ .x = 0.7, .y = 0.55 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠐⠂ @@ -758,12 +758,12 @@ test "line in canvas small x" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0.5, .y = 0.5 }, .{ .x = 0.55, .y = 0.6 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠘⠀ @@ -775,12 +775,12 @@ test "line completly out of canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.line(.{ .x = -0.5, .y = -0.99 }, .{ .x = -0.6, .y = 2 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠀⠀ @@ -792,12 +792,12 @@ test "line flat out of canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.line(.{ .x = -3, .y = -1 }, .{ .x = 3, .y = 1 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠀⠀ @@ -809,12 +809,12 @@ test "line vertical outside canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.line(.{ .x = -0.2, .y = -0.2 }, .{ .x = -0.2, .y = 1.2 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠀⠀ @@ -826,12 +826,12 @@ test "simple rect in canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.rect(.{ .x = 0.2, .y = 0.2 }, .{ .x = 0.7, .y = 0.7 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⢀⣀⡀ \\⢸⠀⡇ @@ -843,12 +843,12 @@ test "simple rect in canvas with chars" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.rect(.{ .x = 0.2, .y = 0.2 }, .{ .x = 0.7, .y = 0.7 }, null, 'O'); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\O⣀O \\⢸⠀⡇ @@ -860,12 +860,12 @@ test "rect through canvas horizontally" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.rect(.{ .x = -0.2, .y = 0.2 }, .{ .x = 1.2, .y = 0.8 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠤⠤⠤ \\⠀⠀⠀ @@ -877,12 +877,12 @@ test "rect through canvas vertically" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.rect(.{ .x = 0.2, .y = -0.2 }, .{ .x = 0.8, .y = 1.2 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⢸⠀⡇ \\⢸⠀⡇ @@ -894,12 +894,12 @@ test "rect outside canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.rect(.{ .x = -0.2, .y = -0.2 }, .{ .x = 1.2, .y = 1.2 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠀⠀ @@ -911,12 +911,12 @@ test "rect in large Canvas" { var c = try Canvas.init(std.testing.allocator, 255, 255, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.rect(.{ .x = -0.2, .y = -0.2 }, .{ .x = 1.2, .y = 1.2 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); const extra = if (@import("builtin").target.os.tag == .windows) 254 else 0; try expectEqual(@as(usize, 195329 + extra), list.items.len); // 3 chars per unicode, 254 linebreaks } @@ -925,12 +925,12 @@ test "text inside canvas" { var c = try Canvas.init(std.testing.allocator, 10, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); c.text(.{ .x = 0.1, .y = 0.5 }, "Hello", null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ \\⠀Hello⠀⠀⠀⠀ @@ -942,12 +942,12 @@ test "text inside canvas too large" { var c = try Canvas.init(std.testing.allocator, 10, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); c.text(.{ .x = 0.1, .y = 0.5 }, "Hello World, how are you?", null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ \\⠀Hello Wor @@ -959,13 +959,13 @@ test "text inside canvas move out left" { var c = try Canvas.init(std.testing.allocator, 10, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); // 5 chars back c.text(.{ .x = -0.5, .y = 0.5 }, "Hello World, how are you?", null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ \\ World, ho @@ -977,13 +977,13 @@ test "text below canvas" { var c = try Canvas.init(std.testing.allocator, 10, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); // 5 chars back c.text(.{ .x = 0.1, .y = -0.5 }, "Hello", null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ @@ -995,13 +995,13 @@ test "text above canvas" { var c = try Canvas.init(std.testing.allocator, 10, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); // 5 chars back c.text(.{ .x = 0.1, .y = 1.5 }, "Hello", null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ @@ -1013,12 +1013,12 @@ test "points with very large coordinates" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); c.point(.{ .x = 1e200, .y = 1e200 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠀⠀ @@ -1029,12 +1029,12 @@ test "points with very small coordinates" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); c.point(.{ .x = -1e200, .y = -1e200 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠀⠀ @@ -1046,12 +1046,12 @@ test "canvas with large height" { var c = try Canvas.init(std.testing.allocator, 128, 65535, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0, .y = 0 }, .{ .x = 1, .y = 1 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); const extra = if (@import("builtin").target.os.tag == .windows) 65534 else 0; try expectEqual(@as(usize, 25_230_974 + extra), list.items.len); // 3 chars per unicode, 65534 linebreaks } @@ -1060,12 +1060,12 @@ test "canvas with large width" { var c = try Canvas.init(std.testing.allocator, 65535, 128, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0, .y = 0 }, .{ .x = 1, .y = 1 }, null, null); - try list.writer(std.testing.allocator).print("{f}", .{c}); + try list.print(std.testing.allocator, "{f}", .{c}); const extra = if (@import("builtin").target.os.tag == .windows) 127 else 0; try expectEqual(@as(usize, 25_165_567 + extra), list.items.len); // 3 chars per unicode, 127 linebreaks } diff --git a/src/color.zig b/src/color.zig index 17020cd..d9fc297 100644 --- a/src/color.zig +++ b/src/color.zig @@ -390,58 +390,58 @@ fn names(color_name: ColorName, is_fg: bool, writer: anytype) !void { test "names with optional fg, bg" { var buff: [100]u8 = undefined; - var fbs = std.io.fixedBufferStream(&buff); - - try names(.red, true, fbs.writer()); - try expectEqual(fbs.pos, 2); - try expectEqualStrings("31", fbs.getWritten()); - fbs.reset(); - - try names(.red, false, fbs.writer()); - try expectEqual(fbs.pos, 2); - try expectEqualStrings("41", fbs.getWritten()); - fbs.reset(); - - try names(.bright_green, true, fbs.writer()); - try expectEqual(fbs.pos, 2); - try expectEqualStrings("92", fbs.getWritten()); - fbs.reset(); - - try names(.bright_green, false, fbs.writer()); - try expectEqual(fbs.pos, 3); - try expectEqualStrings("102", fbs.getWritten()); - fbs.reset(); - - try names(.bright_magenta_old, true, fbs.writer()); - try expectEqual(fbs.pos, 4); - try expectEqualStrings("1;35", fbs.getWritten()); - fbs.reset(); - - try names(.bright_magenta_old, false, fbs.writer()); - try expectEqual(fbs.pos, 4); - try expectEqualStrings("1;45", fbs.getWritten()); - fbs.reset(); + var w: std.Io.Writer = .fixed(&buff); + + try names(.red, true, &w); + try expectEqual(w.end, 2); + try expectEqualStrings("31", w.buffered()); + w.end = 0; + + try names(.red, false, &w); + try expectEqual(w.end, 2); + try expectEqualStrings("41", w.buffered()); + w.end = 0; + + try names(.bright_green, true, &w); + try expectEqual(w.end, 2); + try expectEqualStrings("92", w.buffered()); + w.end = 0; + + try names(.bright_green, false, &w); + try expectEqual(w.end, 3); + try expectEqualStrings("102", w.buffered()); + w.end = 0; + + try names(.bright_magenta_old, true, &w); + try expectEqual(w.end, 4); + try expectEqualStrings("1;35", w.buffered()); + w.end = 0; + + try names(.bright_magenta_old, false, &w); + try expectEqual(w.end, 4); + try expectEqualStrings("1;45", w.buffered()); + w.end = 0; } test "color in names mode" { terminfo.TermInfo.testing(); var buff: [100]u8 = undefined; - var fbs = std.io.fixedBufferStream(&buff); - - try colorPrint(fbs.writer(), "Some text", .{}, .{ .fg = Color.by_name(.red) }); - try expectEqual(fbs.pos, 22); - try expectEqualStrings("\x1b[31mSome text\x1b[39;49m", fbs.getWritten()); - fbs.reset(); - - try colorPrint(fbs.writer(), "Some text", .{}, .{ .bg = Color.by_name(.red) }); - try expectEqual(fbs.pos, 22); - try expectEqualStrings("\x1b[41mSome text\x1b[39;49m", fbs.getWritten()); - fbs.reset(); - - try colorPrint(fbs.writer(), "Some text", .{}, .{ .fg = Color.by_name(.bright_magenta), .bg = Color.by_name(.red) }); - try expectEqual(fbs.pos, 25); - try expectEqualStrings("\x1b[95;41mSome text\x1b[39;49m", fbs.getWritten()); - fbs.reset(); + var w: std.Io.Writer = .fixed(&buff); + + try colorPrint(&w, "Some text", .{}, .{ .fg = Color.by_name(.red) }); + try expectEqual(w.end, 22); + try expectEqualStrings("\x1b[31mSome text\x1b[39;49m", w.buffered()); + w.end = 0; + + try colorPrint(&w, "Some text", .{}, .{ .bg = Color.by_name(.red) }); + try expectEqual(w.end, 22); + try expectEqualStrings("\x1b[41mSome text\x1b[39;49m", w.buffered()); + w.end = 0; + + try colorPrint(&w, "Some text", .{}, .{ .fg = Color.by_name(.bright_magenta), .bg = Color.by_name(.red) }); + try expectEqual(w.end, 25); + try expectEqualStrings("\x1b[95;41mSome text\x1b[39;49m", w.buffered()); + w.end = 0; } const FG_LOOKUP_NUM = "38;5;"; @@ -457,48 +457,48 @@ fn lookups(color_lookup: u8, is_fg: bool, writer: anytype) !void { test "lookups with optional fg, bg" { var buff: [100]u8 = undefined; - var fbs = std.io.fixedBufferStream(&buff); - - try lookups(3, true, fbs.writer()); - try expectEqual(fbs.pos, 6); - try expectEqualStrings("38;5;3", fbs.getWritten()); - fbs.reset(); - - try lookups(25, false, fbs.writer()); - try expectEqual(fbs.pos, 7); - try expectEqualStrings("48;5;25", fbs.getWritten()); - fbs.reset(); - - try lookups(33, true, fbs.writer()); - try expectEqual(fbs.pos, 7); - try expectEqualStrings("38;5;33", fbs.getWritten()); - fbs.reset(); - - try lookups(245, false, fbs.writer()); - try expectEqual(fbs.pos, 8); - try expectEqualStrings("48;5;245", fbs.getWritten()); - fbs.reset(); + var w: std.Io.Writer = .fixed(&buff); + + try lookups(3, true, &w); + try expectEqual(w.end, 6); + try expectEqualStrings("38;5;3", w.buffered()); + w.end = 0; + + try lookups(25, false, &w); + try expectEqual(w.end, 7); + try expectEqualStrings("48;5;25", w.buffered()); + w.end = 0; + + try lookups(33, true, &w); + try expectEqual(w.end, 7); + try expectEqualStrings("38;5;33", w.buffered()); + w.end = 0; + + try lookups(245, false, &w); + try expectEqual(w.end, 8); + try expectEqualStrings("48;5;245", w.buffered()); + w.end = 0; } test "color in lookup mode" { terminfo.TermInfo.testing(); var buff: [100]u8 = undefined; - var fbs = std.io.fixedBufferStream(&buff); - - try colorPrint(fbs.writer(), "Some text", .{}, .{ .fg = Color.by_lookup(44) }); - try expectEqual(fbs.pos, 27); - try expectEqualStrings("\x1b[38;5;44mSome text\x1b[39;49m", fbs.getWritten()); - fbs.reset(); - - try colorPrint(fbs.writer(), "Some text", .{}, .{ .bg = Color.by_lookup(5) }); - try expectEqual(fbs.pos, 26); - try expectEqualStrings("\x1b[48;5;5mSome text\x1b[39;49m", fbs.getWritten()); - fbs.reset(); - - try colorPrint(fbs.writer(), "Some text", .{}, .{ .fg = Color.by_lookup(123), .bg = Color.by_lookup(76) }); - try expectEqual(fbs.pos, 36); - try expectEqualStrings("\x1b[38;5;123;48;5;76mSome text\x1b[39;49m", fbs.getWritten()); - fbs.reset(); + var w: std.Io.Writer = .fixed(&buff); + + try colorPrint(&w, "Some text", .{}, .{ .fg = Color.by_lookup(44) }); + try expectEqual(w.end, 27); + try expectEqualStrings("\x1b[38;5;44mSome text\x1b[39;49m", w.buffered()); + w.end = 0; + + try colorPrint(&w, "Some text", .{}, .{ .bg = Color.by_lookup(5) }); + try expectEqual(w.end, 26); + try expectEqualStrings("\x1b[48;5;5mSome text\x1b[39;49m", w.buffered()); + w.end = 0; + + try colorPrint(&w, "Some text", .{}, .{ .fg = Color.by_lookup(123), .bg = Color.by_lookup(76) }); + try expectEqual(w.end, 36); + try expectEqualStrings("\x1b[38;5;123;48;5;76mSome text\x1b[39;49m", w.buffered()); + w.end = 0; } const FG_RGB_NUM = "38;2;"; @@ -514,67 +514,67 @@ fn rgbs(color_rgb: [3]u8, is_fg: bool, writer: anytype) !void { test "rgbs with optional fg, bg" { var buff: [100]u8 = undefined; - var fbs = std.io.fixedBufferStream(&buff); - - var len = try rgbs([3]u8{ 255, 0, 0 }, true, fbs.writer()); - try expectEqual(fbs.pos, 12); - try expectEqualStrings("38;2;255;0;0", fbs.getWritten()); - fbs.reset(); - - len = try rgbs([_]u8{ 34, 25, 100 }, false, fbs.writer()); - try expectEqual(fbs.pos, 14); - try expectEqualStrings("48;2;34;25;100", fbs.getWritten()); - fbs.reset(); - - len = try rgbs([_]u8{ 1, 2, 3 }, true, fbs.writer()); - try expectEqual(fbs.pos, 10); - try expectEqualStrings("38;2;1;2;3", fbs.getWritten()); - fbs.reset(); - - len = try rgbs([_]u8{ 100, 200, 50 }, false, fbs.writer()); - try expectEqual(fbs.pos, 15); - try expectEqualStrings("48;2;100;200;50", fbs.getWritten()); - fbs.reset(); + var w: std.Io.Writer = .fixed(&buff); + + var len = try rgbs([3]u8{ 255, 0, 0 }, true, &w); + try expectEqual(w.end, 12); + try expectEqualStrings("38;2;255;0;0", w.buffered()); + w.end = 0; + + len = try rgbs([_]u8{ 34, 25, 100 }, false, &w); + try expectEqual(w.end, 14); + try expectEqualStrings("48;2;34;25;100", w.buffered()); + w.end = 0; + + len = try rgbs([_]u8{ 1, 2, 3 }, true, &w); + try expectEqual(w.end, 10); + try expectEqualStrings("38;2;1;2;3", w.buffered()); + w.end = 0; + + len = try rgbs([_]u8{ 100, 200, 50 }, false, &w); + try expectEqual(w.end, 15); + try expectEqualStrings("48;2;100;200;50", w.buffered()); + w.end = 0; } test "color in rgb mode" { terminfo.TermInfo.testing(); var buff: [100]u8 = undefined; - var fbs = std.io.fixedBufferStream(&buff); - - try colorPrint(fbs.writer(), "Some text", .{}, .{ .fg = Color.by_rgb(44, 22, 11) }); - try expectEqual(fbs.pos, 33); - try expectEqualStrings("\x1b[38;2;44;22;11mSome text\x1b[39;49m", fbs.getWritten()); - fbs.reset(); - - try colorPrint(fbs.writer(), "Some text", .{}, .{ .bg = Color.by_rgb(5, 66, 100) }); - try expectEqual(fbs.pos, 33); - try expectEqualStrings("\x1b[48;2;5;66;100mSome text\x1b[39;49m", fbs.getWritten()); - fbs.reset(); - - try colorPrint(fbs.writer(), "Some text", .{}, .{ .fg = Color.by_hsl(123, 0.8, 0.5), .bg = Color.by_rgb(76, 89, 9) }); - try expectEqual(fbs.pos, 47); - try expectEqualStrings("\x1b[38;2;25;229;35;48;2;76;89;9mSome text\x1b[39;49m", fbs.getWritten()); - fbs.reset(); + var w: std.Io.Writer = .fixed(&buff); + + try colorPrint(&w, "Some text", .{}, .{ .fg = Color.by_rgb(44, 22, 11) }); + try expectEqual(w.end, 33); + try expectEqualStrings("\x1b[38;2;44;22;11mSome text\x1b[39;49m", w.buffered()); + w.end = 0; + + try colorPrint(&w, "Some text", .{}, .{ .bg = Color.by_rgb(5, 66, 100) }); + try expectEqual(w.end, 33); + try expectEqualStrings("\x1b[48;2;5;66;100mSome text\x1b[39;49m", w.buffered()); + w.end = 0; + + try colorPrint(&w, "Some text", .{}, .{ .fg = Color.by_hsl(123, 0.8, 0.5), .bg = Color.by_rgb(76, 89, 9) }); + try expectEqual(w.end, 47); + try expectEqualStrings("\x1b[38;2;25;229;35;48;2;76;89;9mSome text\x1b[39;49m", w.buffered()); + w.end = 0; } test "color in mixed modes" { terminfo.TermInfo.testing(); var buff: [100]u8 = undefined; - var fbs = std.io.fixedBufferStream(&buff); - - try colorPrint(fbs.writer(), "Some text", .{}, .{ .fg = Color.by_rgb(44, 22, 11), .bg = Color.by_name(.yellow) }); - try expectEqual(fbs.pos, 36); - try expectEqualStrings("\x1b[38;2;44;22;11;43mSome text\x1b[39;49m", fbs.getWritten()); - fbs.reset(); - - try colorPrint(fbs.writer(), "Some text", .{}, .{ .fg = Color.by_lookup(155), .bg = Color.by_rgb(5, 66, 100) }); - try expectEqual(fbs.pos, 42); - try expectEqualStrings("\x1b[38;5;155;48;2;5;66;100mSome text\x1b[39;49m", fbs.getWritten()); - fbs.reset(); - - try colorPrint(fbs.writer(), "Some text", .{}, .{ .fg = Color.by_name(.bright_cyan_old), .bg = Color.by_lookup(254) }); - try expectEqual(fbs.pos, 33); - try expectEqualStrings("\x1b[1;36;48;5;254mSome text\x1b[39;49m", fbs.getWritten()); - fbs.reset(); + var w: std.Io.Writer = .fixed(&buff); + + try colorPrint(&w, "Some text", .{}, .{ .fg = Color.by_rgb(44, 22, 11), .bg = Color.by_name(.yellow) }); + try expectEqual(w.end, 36); + try expectEqualStrings("\x1b[38;2;44;22;11;43mSome text\x1b[39;49m", w.buffered()); + w.end = 0; + + try colorPrint(&w, "Some text", .{}, .{ .fg = Color.by_lookup(155), .bg = Color.by_rgb(5, 66, 100) }); + try expectEqual(w.end, 42); + try expectEqualStrings("\x1b[38;5;155;48;2;5;66;100mSome text\x1b[39;49m", w.buffered()); + w.end = 0; + + try colorPrint(&w, "Some text", .{}, .{ .fg = Color.by_name(.bright_cyan_old), .bg = Color.by_lookup(254) }); + try expectEqual(w.end, 33); + try expectEqualStrings("\x1b[1;36;48;5;254mSome text\x1b[39;49m", w.buffered()); + w.end = 0; } diff --git a/src/dots.zig b/src/dots.zig index 9344040..f90a1ab 100644 --- a/src/dots.zig +++ b/src/dots.zig @@ -85,193 +85,193 @@ pub const Dots = extern struct { test "test clear and full char" { var buff: [100]u8 = undefined; - var fbs = std.io.fixedBufferStream(&buff); + var w: std.Io.Writer = .fixed(&buff); var d = Dots{}; - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠀", w.buffered()); + w.end = 0; d.fill(); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⣿", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⣿", w.buffered()); + w.end = 0; d.clear(); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠀", w.buffered()); + w.end = 0; } test "set and unset individual vals" { var buff: [100]u8 = undefined; - var fbs = std.io.fixedBufferStream(&buff); + var w: std.Io.Writer = .fixed(&buff); var d = Dots{}; - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠀", w.buffered()); + w.end = 0; d.set(0, 0); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⡀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⡀", w.buffered()); + w.end = 0; d.unset(0, 0); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠀", w.buffered()); + w.end = 0; d.set(0, 1); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠄", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠄", w.buffered()); + w.end = 0; d.unset(0, 1); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠀", w.buffered()); + w.end = 0; d.set(0, 2); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠂", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠂", w.buffered()); + w.end = 0; d.unset(0, 2); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠀", w.buffered()); + w.end = 0; d.set(0, 3); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠁", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠁", w.buffered()); + w.end = 0; d.unset(0, 3); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠀", w.buffered()); + w.end = 0; d.set(1, 0); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⢀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⢀", w.buffered()); + w.end = 0; d.unset(1, 0); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠀", w.buffered()); + w.end = 0; d.set(1, 1); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠠", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠠", w.buffered()); + w.end = 0; d.unset(1, 1); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠀", w.buffered()); + w.end = 0; d.set(1, 2); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠐", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠐", w.buffered()); + w.end = 0; d.unset(1, 2); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠀", w.buffered()); + w.end = 0; d.set(1, 3); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠈", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠈", w.buffered()); + w.end = 0; d.unset(1, 3); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠀", w.buffered()); + w.end = 0; } test "colored dots" { terminfo.TermInfo.testing(); var buff: [100]u8 = undefined; - var fbs = std.io.fixedBufferStream(&buff); + var w: std.Io.Writer = .fixed(&buff); var d = Dots{}; d.set(0, 0); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⡀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⡀", w.buffered()); + w.end = 0; d.color.fg = color.Color.by_name(.red); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqual(fbs.pos, 16); - try expectEqualStrings("\x1b[31m⡀\x1b[39;49m", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqual(w.end, 16); + try expectEqualStrings("\x1b[31m⡀\x1b[39;49m", w.buffered()); + w.end = 0; d.color.bg = color.Color.by_lookup(123); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqual(fbs.pos, 25); - try expectEqualStrings("\x1b[31;48;5;123m⡀\x1b[39;49m", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqual(w.end, 25); + try expectEqualStrings("\x1b[31;48;5;123m⡀\x1b[39;49m", w.buffered()); + w.end = 0; d.color.fg = color.Color.by_rgb(1, 22, 133); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqual(fbs.pos, 36); - try expectEqualStrings("\x1b[38;2;1;22;133;48;5;123m⡀\x1b[39;49m", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqual(w.end, 36); + try expectEqualStrings("\x1b[38;2;1;22;133;48;5;123m⡀\x1b[39;49m", w.buffered()); + w.end = 0; } test "set / unset char" { var buff: [100]u8 = undefined; - var fbs = std.io.fixedBufferStream(&buff); + var w: std.Io.Writer = .fixed(&buff); var d = Dots{}; d.char = 'x'; - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("x", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("x", w.buffered()); + w.end = 0; d.clear(); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠀", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠀", w.buffered()); + w.end = 0; } test "color char" { terminfo.TermInfo.testing(); var buff: [100]u8 = undefined; - var fbs = std.io.fixedBufferStream(&buff); + var w: std.Io.Writer = .fixed(&buff); var d = Dots{}; d.char = 'x'; d.color.fg = color.Color.by_rgb(111, 222, 255); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("\x1b[38;2;111;222;255mx\x1b[39;49m", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("\x1b[38;2;111;222;255mx\x1b[39;49m", w.buffered()); + w.end = 0; } test "set char and dots" { var buff: [100]u8 = undefined; - var fbs = std.io.fixedBufferStream(&buff); + var w: std.Io.Writer = .fixed(&buff); var d = Dots{}; d.char = 'x'; - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("x", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("x", w.buffered()); + w.end = 0; d.set(0, 1); - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("x", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("x", w.buffered()); + w.end = 0; d.char = 0; - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("⠄", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("⠄", w.buffered()); + w.end = 0; d.char = 'o'; - try std.fmt.format(fbs.writer(), "{f}", .{d}); - try expectEqualStrings("o", fbs.getWritten()); - fbs.reset(); + try w.print("{f}", .{d}); + try expectEqualStrings("o", w.buffered()); + w.end = 0; } diff --git a/src/figure.zig b/src/figure.zig index c7b77b5..b35058b 100644 --- a/src/figure.zig +++ b/src/figure.zig @@ -55,10 +55,10 @@ pub const Figure = struct { .x_label = try allocator.dupe(u8, "X"), .y_label = try allocator.dupe(u8, "Y"), ._canvas = null, - ._plots = .{}, - ._histograms = .{}, - ._texts = .{}, - ._spans = .{}, + ._plots = .empty, + ._histograms = .empty, + ._texts = .empty, + ._spans = .empty, .allocator = allocator, }; } @@ -500,10 +500,10 @@ test "working test" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\3.000 | @@ -535,10 +535,10 @@ test "figure with axvline center" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -566,10 +566,10 @@ test "figure with axvline center center" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -597,10 +597,10 @@ test "figure with axvline left" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -628,10 +628,10 @@ test "figure with axvline right" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -659,10 +659,10 @@ test "figure with axvspan border" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -690,10 +690,10 @@ test "figure with axvspan center" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -721,10 +721,10 @@ test "figure with axvspan center center" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -752,10 +752,10 @@ test "figure with axhline center" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -783,10 +783,10 @@ test "figure with axhline center center" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -814,10 +814,10 @@ test "figure with axhline bottom" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -845,10 +845,10 @@ test "figure with axhline top" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -876,10 +876,10 @@ test "figure with axhspan border" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -907,10 +907,10 @@ test "figure with axhspan center" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -938,10 +938,10 @@ test "figure with axhspan center center" { try fig.prepare(); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{fig}); + try list.print(std.testing.allocator, "{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | diff --git a/src/hist.zig b/src/hist.zig index d7adc24..fd50e80 100644 --- a/src/hist.zig +++ b/src/hist.zig @@ -243,10 +243,10 @@ test "write simple Histogram" { var h = try Histogram.init(testing.allocator, &values, 12); defer h.deinit(testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{h.withWidth(60)}); + try list.print(std.testing.allocator, "{f}", .{h.withWidth(60)}); try expectEqualStringsNormalized( \\ bucket | ____________________________________________________________ Total Counts @@ -277,10 +277,10 @@ test "write random Histogram" { var h = try Histogram.init(testing.allocator, &values, 10); defer h.deinit(testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{h.withWidth(40)}); + try list.print(std.testing.allocator, "{f}", .{h.withWidth(40)}); try expectEqualStringsNormalized( \\ bucket | ________________________________________ Total Counts @@ -309,10 +309,10 @@ test "write large random Histogram" { var h = try Histogram.init(testing.allocator, &values, 10); defer h.deinit(testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{h}); + try list.print(std.testing.allocator, "{f}", .{h}); try expectEqualStringsNormalized( \\ bucket | ________________________________________________________________________________ Total Counts @@ -341,10 +341,10 @@ test "write small random Histogram" { var h = try Histogram.init(testing.allocator, &values, 10); defer h.deinit(testing.allocator); - var list: std.ArrayList(u8) = .{}; + var list: std.ArrayList(u8) = .empty; defer list.deinit(std.testing.allocator); - try list.writer(std.testing.allocator).print("{f}", .{h}); + try list.print(std.testing.allocator, "{f}", .{h}); try expectEqualStringsNormalized( \\ bucket | ________________________________________________________________________________ Total Counts diff --git a/src/terminfo.zig b/src/terminfo.zig index 9d28b22..75b99e1 100644 --- a/src/terminfo.zig +++ b/src/terminfo.zig @@ -72,11 +72,13 @@ pub const TermInfo = extern struct { } /// Read out environment variables, hence the allocator. - pub fn detect(allocator: std.mem.Allocator) !void { - const stdout_tty = std.posix.isatty(std.fs.File.stdout().handle); - const no_color = isNoColorSet(allocator); - const force_color = try forceColors(allocator); - const color_mode = try getColorMode(allocator); + /// `io` is used to check whether stdout is a tty, `environ` provides the + /// environment variables of the process (see `std.process.Init`). + pub fn detect(io: std.Io, environ: std.process.Environ, allocator: std.mem.Allocator) !void { + const stdout_tty = try std.Io.File.stdout().isTty(io); + const no_color = isNoColorSet(environ, allocator); + const force_color = try forceColors(environ, allocator); + const color_mode = try getColorMode(environ, allocator); info = TermInfo{ .stdout_tty = stdout_tty, @@ -87,18 +89,18 @@ pub const TermInfo = extern struct { } /// free on its own - fn isNoColorSet(allocator: std.mem.Allocator) bool { + fn isNoColorSet(environ: std.process.Environ, allocator: std.mem.Allocator) bool { // on windows needs allocator to put key into utf16 // https://no-color.org/ - return std.process.hasEnvVar(allocator, "NO_COLOR") catch unreachable; + return environ.contains(allocator, "NO_COLOR") catch unreachable; } /// free on its own - fn forceColors(allocator: std.mem.Allocator) !ForceColor { + fn forceColors(environ: std.process.Environ, allocator: std.mem.Allocator) !ForceColor { // https://nodejs.org/api/tty.html#tty_writestream_getcolordepth_env var force_color: ForceColor = ForceColor.none; // on issues, ignore force_color - const opt_force_color_str = try getEnvVar(allocator, "FORCE_COLOR"); + const opt_force_color_str = try getEnvVar(environ, allocator, "FORCE_COLOR"); if (opt_force_color_str) |force_color_str| { defer allocator.free(force_color_str); if (std.ascii.eqlIgnoreCase(force_color_str, "0") or std.ascii.eqlIgnoreCase(force_color_str, "false") or std.ascii.eqlIgnoreCase(force_color_str, "none")) { @@ -110,12 +112,12 @@ pub const TermInfo = extern struct { return force_color; } /// free on its own - fn getColorMode(allocator: std.mem.Allocator) !color.ColorMode { - if (isWindowsTerminal(allocator) or isDomTerm(allocator) or isKittyTerm(allocator)) { + fn getColorMode(environ: std.process.Environ, allocator: std.mem.Allocator) !color.ColorMode { + if (isWindowsTerminal(environ, allocator) or isDomTerm(environ, allocator) or isKittyTerm(environ, allocator)) { return .rgb; } - const opt_colorterm = try getEnvVar(allocator, "COLORTERM"); + const opt_colorterm = try getEnvVar(environ, allocator, "COLORTERM"); if (opt_colorterm) |colorterm| { defer allocator.free(colorterm); for (rgb_level) |rgb_lvl| { @@ -125,7 +127,7 @@ pub const TermInfo = extern struct { } } - const opt_termprogram = try getEnvVar(allocator, "TERM_PROGRAM"); + const opt_termprogram = try getEnvVar(environ, allocator, "TERM_PROGRAM"); if (opt_termprogram) |termprogram| { defer allocator.free(termprogram); for (rgb_termprogs) |name| { @@ -134,7 +136,7 @@ pub const TermInfo = extern struct { } } if (std.mem.eql(u8, "iterm.app", termprogram)) { - return try checkiTerm(allocator); + return try checkiTerm(environ, allocator); } for (lookup_termprogs) |name| { if (std.mem.eql(u8, name, termprogram)) { @@ -144,7 +146,7 @@ pub const TermInfo = extern struct { // TODO: iterm => lookup , iterm >=3 => rgb via TERM_PROGRAM_VERSION } - const opt_term = try getEnvVar(allocator, "TERM"); + const opt_term = try getEnvVar(environ, allocator, "TERM"); if (opt_term) |term| { defer allocator.free(term); @@ -187,34 +189,34 @@ pub const TermInfo = extern struct { return .none; } /// free on its own - fn isWindowsTerminal(allocator: std.mem.Allocator) bool { + fn isWindowsTerminal(environ: std.process.Environ, allocator: std.mem.Allocator) bool { // on windows needs allocator to put key into utf16 // https://github.com/microsoft/terminal/issues/1040#issuecomment-496691842 - if (std.process.getEnvVarOwned(allocator, "WT_SESSION")) |wt_session| { + if (environ.getAlloc(allocator, "WT_SESSION")) |wt_session| { defer allocator.free(wt_session); return wt_session.len > 0; } else |err| switch (err) { - error.EnvironmentVariableNotFound => return false, + error.EnvironmentVariableMissing => return false, // oom or utf8 errors, hence var is set and more than on char else => return true, } } /// free on its own - fn isDomTerm(allocator: std.mem.Allocator) bool { + fn isDomTerm(environ: std.process.Environ, allocator: std.mem.Allocator) bool { // on windows needs allocator to put key into utf16 // https://domterm.org/Detecting-domterm-terminal.html - return std.process.hasEnvVar(allocator, "DOMTERM") catch unreachable; + return environ.contains(allocator, "DOMTERM") catch unreachable; } /// free on its own - fn isKittyTerm(allocator: std.mem.Allocator) bool { + fn isKittyTerm(environ: std.process.Environ, allocator: std.mem.Allocator) bool { // on windows needs allocator to put key into utf16 // https://github.com/kovidgoyal/kitty/issues/957#issuecomment-420318828 - return std.process.hasEnvVar(allocator, "KITTY_WINDOW_ID") catch unreachable; + return environ.contains(allocator, "KITTY_WINDOW_ID") catch unreachable; } /// free on its own /// assumes that TERM_PROGRAM lower == iterm.app - fn checkiTerm(allocator: std.mem.Allocator) !color.ColorMode { - const opt_version = try getEnvVar(allocator, "TERM_PROGRAM_VERSION"); + fn checkiTerm(environ: std.process.Environ, allocator: std.mem.Allocator) !color.ColorMode { + const opt_version = try getEnvVar(environ, allocator, "TERM_PROGRAM_VERSION"); if (opt_version) |version| { defer allocator.free(version); // get major version @@ -231,27 +233,28 @@ pub const TermInfo = extern struct { } /// free returned string /// Get optional and lowercase string. - fn getEnvVar(allocator: std.mem.Allocator, name: []const u8) !?[]const u8 { - if (std.process.getEnvVarOwned(allocator, name)) |value| { + fn getEnvVar(environ: std.process.Environ, allocator: std.mem.Allocator, name: []const u8) !?[]const u8 { + if (environ.getAlloc(allocator, name)) |value| { defer allocator.free(value); return try std.ascii.allocLowerString(allocator, value); } else |err| switch (err) { - error.EnvironmentVariableNotFound => return null, + error.EnvironmentVariableMissing => return null, else => |e| return e, } } }; test "detect frees memory" { - try TermInfo.detect(std.testing.allocator); - _ = TermInfo.isNoColorSet(std.testing.allocator); - _ = try TermInfo.forceColors(std.testing.allocator); - _ = try TermInfo.getColorMode(std.testing.allocator); - _ = TermInfo.isWindowsTerminal(std.testing.allocator); - _ = TermInfo.isDomTerm(std.testing.allocator); - _ = TermInfo.isKittyTerm(std.testing.allocator); - _ = try TermInfo.checkiTerm(std.testing.allocator); - const opt_term = try TermInfo.getEnvVar(std.testing.allocator, "TERM"); + const environ = std.testing.environ; + try TermInfo.detect(std.testing.io, environ, std.testing.allocator); + _ = TermInfo.isNoColorSet(environ, std.testing.allocator); + _ = try TermInfo.forceColors(environ, std.testing.allocator); + _ = try TermInfo.getColorMode(environ, std.testing.allocator); + _ = TermInfo.isWindowsTerminal(environ, std.testing.allocator); + _ = TermInfo.isDomTerm(environ, std.testing.allocator); + _ = TermInfo.isKittyTerm(environ, std.testing.allocator); + _ = try TermInfo.checkiTerm(environ, std.testing.allocator); + const opt_term = try TermInfo.getEnvVar(environ, std.testing.allocator, "TERM"); if (opt_term) |term| { defer std.testing.allocator.free(term); } diff --git a/zig-examples/build.zig.zon b/zig-examples/build.zig.zon index 918fba7..f3dffc4 100644 --- a/zig-examples/build.zig.zon +++ b/zig-examples/build.zig.zon @@ -1,7 +1,7 @@ .{ .name = .house, - .version = "0.0.1", - .minimum_zig_version = "0.15.2", + .version = "0.1.0", + .minimum_zig_version = "0.16.0", .dependencies = .{ .plotille = .{ .path = "..", diff --git a/zig-examples/dots.zig b/zig-examples/dots.zig index 9c11c1b..4062b72 100644 --- a/zig-examples/dots.zig +++ b/zig-examples/dots.zig @@ -1,16 +1,17 @@ const std = @import("std"); const plt = @import("plotille"); -pub fn main() !void { - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - const allocator = arena.allocator(); +pub fn main(init: std.process.Init) !void { + const allocator = init.arena.allocator(); + const io = init.io; // detect terminal information - try plt.terminfo.TermInfo.detect(allocator); + try plt.terminfo.TermInfo.detect(io, init.minimal.environ, allocator); - var stdout_writer = std.fs.File.stdout().writer(&.{}); + var stdout_buffer: [4096]u8 = undefined; + var stdout_writer: std.Io.File.Writer = .init(.stdout(), io, &stdout_buffer); const writer = &stdout_writer.interface; + defer writer.flush() catch {}; var dot = plt.dots.Dots{}; dot.set(0, 0); // Top-left diff --git a/zig-examples/hist.zig b/zig-examples/hist.zig index 3510a43..a067f8c 100644 --- a/zig-examples/hist.zig +++ b/zig-examples/hist.zig @@ -23,17 +23,17 @@ fn usage() void { , .{}); } -pub fn main() !void { - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - const allocator = arena.allocator(); +pub fn main(init: std.process.Init) !void { + const allocator = init.arena.allocator(); + const io = init.io; - try TermInfo.detect(allocator); - var stdout_writer = std.fs.File.stdout().writer(&.{}); + try TermInfo.detect(io, init.minimal.environ, allocator); + var stdout_buffer: [4096]u8 = undefined; + var stdout_writer: std.Io.File.Writer = .init(.stdout(), io, &stdout_buffer); const writer = &stdout_writer.interface; + defer writer.flush() catch {}; - const args = try std.process.argsAlloc(allocator); - defer std.process.argsFree(allocator, args); + const args = try init.minimal.args.toSlice(allocator); if (args.len == 1) { usage(); @@ -49,7 +49,7 @@ pub fn main() !void { use_stdin = true; } - var values: std.ArrayList(f64) = .{}; + var values: std.ArrayList(f64) = .empty; defer values.deinit(allocator); if (!use_stdin) { @@ -62,8 +62,9 @@ pub fn main() !void { try values.append(allocator, val); } } else { - const stdin_file = std.fs.File.stdin(); - const in = try stdin_file.readToEndAlloc(allocator, 1 << 20); + var stdin_buffer: [4096]u8 = undefined; + var stdin_reader = std.Io.File.stdin().readerStreaming(io, &stdin_buffer); + const in = try stdin_reader.interface.allocRemaining(allocator, .limited(1 << 20)); defer allocator.free(in); var it = std.mem.tokenizeAny(u8, in, " \r\n\t"); while (it.next()) |arg| { diff --git a/zig-examples/histogram.zig b/zig-examples/histogram.zig index cf6f7cd..9534ce0 100644 --- a/zig-examples/histogram.zig +++ b/zig-examples/histogram.zig @@ -23,17 +23,17 @@ fn usage() void { , .{}); } -pub fn main() !void { - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - const allocator = arena.allocator(); +pub fn main(init: std.process.Init) !void { + const allocator = init.arena.allocator(); + const io = init.io; - try TermInfo.detect(allocator); - var stdout_writer = std.fs.File.stdout().writer(&.{}); + try TermInfo.detect(io, init.minimal.environ, allocator); + var stdout_buffer: [4096]u8 = undefined; + var stdout_writer: std.Io.File.Writer = .init(.stdout(), io, &stdout_buffer); const writer = &stdout_writer.interface; + defer writer.flush() catch {}; - const args = try std.process.argsAlloc(allocator); - defer std.process.argsFree(allocator, args); + const args = try init.minimal.args.toSlice(allocator); if (args.len == 1) { usage(); @@ -49,7 +49,7 @@ pub fn main() !void { use_stdin = true; } - var values: std.ArrayList(f64) = .{}; + var values: std.ArrayList(f64) = .empty; defer values.deinit(allocator); if (!use_stdin) { @@ -62,8 +62,9 @@ pub fn main() !void { try values.append(allocator, val); } } else { - const stdin_file = std.fs.File.stdin(); - const in = try stdin_file.readToEndAlloc(allocator, 1 << 20); + var stdin_buffer: [4096]u8 = undefined; + var stdin_reader = std.Io.File.stdin().readerStreaming(io, &stdin_buffer); + const in = try stdin_reader.interface.allocRemaining(allocator, .limited(1 << 20)); defer allocator.free(in); var it = std.mem.tokenizeAny(u8, in, " \r\n\t"); while (it.next()) |arg| { diff --git a/zig-examples/house.zig b/zig-examples/house.zig index 734186f..2441cd2 100644 --- a/zig-examples/house.zig +++ b/zig-examples/house.zig @@ -3,14 +3,15 @@ const std = @import("std"); const plt = @import("plotille"); const TermInfo = plt.terminfo.TermInfo; -pub fn main() !void { - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - const allocator = arena.allocator(); +pub fn main(init: std.process.Init) !void { + const allocator = init.arena.allocator(); + const io = init.io; - try TermInfo.detect(allocator); - var stdout_writer = std.fs.File.stdout().writer(&.{}); + try TermInfo.detect(io, init.minimal.environ, allocator); + var stdout_buffer: [4096]u8 = undefined; + var stdout_writer: std.Io.File.Writer = .init(.stdout(), io, &stdout_buffer); const writer = &stdout_writer.interface; + defer writer.flush() catch {}; var canvas = try plt.canvas.Canvas.init(allocator, 40, 20, plt.color.Color.by_name(.white)); defer canvas.deinit(allocator); diff --git a/zig-examples/hsl.zig b/zig-examples/hsl.zig index 790b0cf..8c38dc9 100644 --- a/zig-examples/hsl.zig +++ b/zig-examples/hsl.zig @@ -26,19 +26,19 @@ const max_col: f64 = 40; const max_rows: f64 = 20; const space = " "; -pub fn main() !void { - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - const allocator = arena.allocator(); +pub fn main(init: std.process.Init) !void { + const allocator = init.arena.allocator(); + const io = init.io; // detect terminal information - try plt.terminfo.TermInfo.detect(allocator); + try plt.terminfo.TermInfo.detect(io, init.minimal.environ, allocator); - var stdout_writer = std.fs.File.stdout().writer(&.{}); + var stdout_buffer: [4096]u8 = undefined; + var stdout_writer: std.Io.File.Writer = .init(.stdout(), io, &stdout_buffer); const writer = &stdout_writer.interface; + defer writer.flush() catch {}; - const args = try std.process.argsAlloc(allocator); - defer std.process.argsFree(allocator, args); + const args = try init.minimal.args.toSlice(allocator); if (args.len == 1) { usage(); diff --git a/zig-examples/lookup.zig b/zig-examples/lookup.zig index b57cf7c..0d18064 100644 --- a/zig-examples/lookup.zig +++ b/zig-examples/lookup.zig @@ -2,15 +2,16 @@ const std = @import("std"); const plt = @import("plotille"); -pub fn main() !void { - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - const allocator = arena.allocator(); +pub fn main(init: std.process.Init) !void { + const allocator = init.arena.allocator(); + const io = init.io; // detect terminal information - try plt.terminfo.TermInfo.detect(allocator); - var stdout_writer = std.fs.File.stdout().writer(&.{}); + try plt.terminfo.TermInfo.detect(io, init.minimal.environ, allocator); + var stdout_buffer: [4096]u8 = undefined; + var stdout_writer: std.Io.File.Writer = .init(.stdout(), io, &stdout_buffer); const writer = &stdout_writer.interface; + defer writer.flush() catch {}; var int_buff: [4]u8 = undefined; const fg_black = plt.color.Color.by_lookup(16); @@ -23,8 +24,7 @@ pub fn main() !void { while (idx <= 7) : (idx += 1) { const bg = plt.color.Color.by_lookup(@truncate(idx)); const int_str = try std.fmt.bufPrint(int_buff[0..], "{:4}", .{idx}); - var color_writer = std.fs.File.stdout().writer(&.{}); - try plt.color.colorPrint(&color_writer.interface, "{s}", .{int_str}, .{ .fg = fg_white, .bg = bg }); + try plt.color.colorPrint(writer, "{s}", .{int_str}, .{ .fg = fg_white, .bg = bg }); } try writer.print("\n", .{}); @@ -32,8 +32,7 @@ pub fn main() !void { while (idx <= 15) : (idx += 1) { const bg = plt.color.Color.by_lookup(@truncate(idx)); const int_str = try std.fmt.bufPrint(int_buff[0..], "{:4}", .{idx}); - var color_writer = std.fs.File.stdout().writer(&.{}); - try plt.color.colorPrint(&color_writer.interface, "{s}", .{int_str}, .{ .fg = fg_black, .bg = bg }); + try plt.color.colorPrint(writer, "{s}", .{int_str}, .{ .fg = fg_black, .bg = bg }); } try writer.print("\n", .{}); @@ -52,11 +51,9 @@ pub fn main() !void { const bg = plt.color.Color.by_lookup(@truncate(idx)); const int_str = try std.fmt.bufPrint(int_buff[0..], "{:4}", .{idx}); if ((idx - 16) % 36 >= 18) { - var color_writer = std.fs.File.stdout().writer(&.{}); - try plt.color.colorPrint(&color_writer.interface, "{s}", .{int_str}, .{ .fg = fg_black, .bg = bg }); + try plt.color.colorPrint(writer, "{s}", .{int_str}, .{ .fg = fg_black, .bg = bg }); } else { - var color_writer = std.fs.File.stdout().writer(&.{}); - try plt.color.colorPrint(&color_writer.interface, "{s}", .{int_str}, .{ .fg = fg_white, .bg = bg }); + try plt.color.colorPrint(writer, "{s}", .{int_str}, .{ .fg = fg_white, .bg = bg }); } } try writer.print("\n", .{}); @@ -66,11 +63,9 @@ pub fn main() !void { const bg = plt.color.Color.by_lookup(@truncate(idx)); const int_str = try std.fmt.bufPrint(int_buff[0..], "{:4}", .{idx}); if (idx < 244) { - var color_writer = std.fs.File.stdout().writer(&.{}); - try plt.color.colorPrint(&color_writer.interface, "{s}", .{int_str}, .{ .fg = fg_white, .bg = bg }); + try plt.color.colorPrint(writer, "{s}", .{int_str}, .{ .fg = fg_white, .bg = bg }); } else { - var color_writer = std.fs.File.stdout().writer(&.{}); - try plt.color.colorPrint(&color_writer.interface, "{s}", .{int_str}, .{ .fg = fg_black, .bg = bg }); + try plt.color.colorPrint(writer, "{s}", .{int_str}, .{ .fg = fg_black, .bg = bg }); } } try writer.print("\n", .{}); diff --git a/zig-examples/names.zig b/zig-examples/names.zig index 25e99a3..c51e6cc 100644 --- a/zig-examples/names.zig +++ b/zig-examples/names.zig @@ -2,16 +2,17 @@ const std = @import("std"); const plt = @import("plotille"); -pub fn main() !void { - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - const allocator = arena.allocator(); +pub fn main(init: std.process.Init) !void { + const allocator = init.arena.allocator(); + const io = init.io; // detect terminal information - try plt.terminfo.TermInfo.detect(allocator); + try plt.terminfo.TermInfo.detect(io, init.minimal.environ, allocator); - var stdout_writer = std.fs.File.stdout().writer(&.{}); + var stdout_buffer: [4096]u8 = undefined; + var stdout_writer: std.Io.File.Writer = .init(.stdout(), io, &stdout_buffer); const writer = &stdout_writer.interface; + defer writer.flush() catch {}; try writer.print("Colors by name: ", .{}); for (std.enums.values(plt.color.ColorName)) |color_value| { diff --git a/zig-examples/sine.zig b/zig-examples/sine.zig index b81a195..87b4a0b 100644 --- a/zig-examples/sine.zig +++ b/zig-examples/sine.zig @@ -4,16 +4,17 @@ const plt = @import("plotille"); const pi = 3.141592653589793; -pub fn main() !void { - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - const allocator = arena.allocator(); +pub fn main(init: std.process.Init) !void { + const allocator = init.arena.allocator(); + const io = init.io; // detect terminal information - try plt.terminfo.TermInfo.detect(allocator); + try plt.terminfo.TermInfo.detect(io, init.minimal.environ, allocator); - var stdout_writer = std.fs.File.stdout().writer(&.{}); + var stdout_buffer: [4096]u8 = undefined; + var stdout_writer: std.Io.File.Writer = .init(.stdout(), io, &stdout_buffer); const writer = &stdout_writer.interface; + defer writer.flush() catch {}; var fig = try plt.figure.Figure.init(allocator, 60, 20, null); defer fig.deinit(); diff --git a/zig-examples/terminfo.zig b/zig-examples/terminfo.zig index 2495e90..40e2f81 100644 --- a/zig-examples/terminfo.zig +++ b/zig-examples/terminfo.zig @@ -4,15 +4,16 @@ const json = std.json; const plt = @import("plotille"); const TermInfo = plt.terminfo.TermInfo; -pub fn main() !void { - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - defer _ = gpa.deinit(); - const allocator = gpa.allocator(); +pub fn main(init: std.process.Init) !void { + const allocator = init.gpa; + const io = init.io; - try TermInfo.detect(allocator); + try TermInfo.detect(io, init.minimal.environ, allocator); const info = TermInfo.get(); - var stdout_writer = std.fs.File.stdout().writer(&.{}); + var stdout_buffer: [4096]u8 = undefined; + var stdout_writer: std.Io.File.Writer = .init(.stdout(), io, &stdout_buffer); const writer = &stdout_writer.interface; + defer writer.flush() catch {}; try writer.print("{f}\n", .{json.fmt(info, .{})}); }