diff options
Diffstat (limited to 'build.zig')
| -rw-r--r-- | build.zig | 70 |
1 files changed, 68 insertions, 2 deletions
@@ -864,11 +864,65 @@ pub fn build(b: *std.Build) void { \\} \\ ; + // vaxis's render, patched the same way: a blank whose ink alone + // changed is not sent, since a blank's ink shows nowhere. A fade + // (InactiveDim on a focus change) sent every blank of every pane it + // touched again: 7 KB a click for three shell panes. The terminal + // keeps the old ink there, and so does vaxis's last frame. + const render_path = vaxis_dep.path("src/Vaxis.zig").getPath(b); + var render_src = std.Io.Dir.cwd().readFileAlloc(io, render_path, b.allocator, .limited(1 << 20)) catch @panic("read vaxis Vaxis.zig"); + const render_anchor = + \\ if ((!self.refresh and + \\ last.eql(cell) and + ; + if (std.mem.count(u8, render_src, render_anchor) != 1) std.debug.panic("vaxis's Vaxis.zig changed at `{s}`: redo its patch in build.zig", .{render_anchor}); + render_src = std.mem.replaceOwned(u8, b.allocator, render_src, render_anchor, + \\ if ((!self.refresh and + \\ (last.eql(cell) or blankInkOnly(&last, &cell)) and // pardes's patch (its build.zig) + \\ + ) catch @panic("OOM"); + // And the secondary cursors count as changed when they differ, not + // when they are the same: read the other way round, every render + // started a frame, ~40 bytes to the terminal with nothing changed. + const secondary_anchor = " std.meta.eql(self.screen.cursor_secondary, self.state.cursor_secondary);\n"; + if (std.mem.count(u8, render_src, secondary_anchor) != 1) std.debug.panic("vaxis's Vaxis.zig changed at `{s}`: redo its patch in build.zig", .{secondary_anchor}); + render_src = std.mem.replaceOwned(u8, b.allocator, render_src, secondary_anchor, " !std.meta.eql(self.screen.cursor_secondary, self.state.cursor_secondary); // pardes's patch (its build.zig)\n") catch @panic("OOM"); + const blank_ink = + \\ + \\/// pardes's patch (its build.zig): a blank cell (a space, no underline, + \\/// strike or reverse) that differs from the last frame's blank in its + \\/// ink alone, which shows nowhere. + \\inline fn blankInkOnly(last: *const InternalScreen.InternalCell, cell: *const Cell) bool { + \\ if (!(cell.char.grapheme.len == 1 and cell.char.grapheme[0] == ' ')) return false; + \\ if (last.default or cell.default) return false; + \\ if (!(last.char.items.len == 1 and last.char.items[0] == ' ')) return false; + \\ const s = cell.style; + \\ if (s.reverse or s.strikethrough or s.ul_style != .off) return false; + \\ if (!std.mem.eql(u8, last.uri.items, cell.link.uri)) return false; + \\ // Field by field: Style.eql is slow, and this runs for every blank + \\ // a scrolling shell moves. + \\ const l = last.style; + \\ return sameColor(l.bg, s.bg) and sameColor(l.ul, s.ul) and l.ul_style == s.ul_style and + \\ l.bold == s.bold and l.dim == s.dim and l.italic == s.italic and l.blink == s.blink and + \\ !l.reverse and !l.strikethrough and l.invisible == s.invisible; + \\} + \\ + \\inline fn sameColor(a: Cell.Color, b: Cell.Color) bool { + \\ return switch (a) { + \\ .default => b == .default, + \\ .index => |i| b == .index and b.index == i, + \\ .rgb => |rgb| b == .rgb and rgb[0] == b.rgb[0] and rgb[1] == b.rgb[1] and rgb[2] == b.rgb[2], + \\ }; + \\} + \\ + ; const files = b.addWriteFiles(); _ = files.add("Parser.zig", b.fmt("{s}{s}", .{ src, cursor_report })); + _ = files.add("Vaxis.zig", b.fmt("{s}{s}", .{ render_src, blank_ink })); _ = files.addCopyFile(vaxis_dep.path("src/widgets/terminal/Parser.zig"), "widgets/terminal/Parser.zig"); - // Suffixes: this leaves out both Parser.zig files, written above. - _ = files.addCopyDirectory(vaxis_dep.path("src"), "", .{ .exclude_extensions = &.{"Parser.zig"} }); + // Suffixes: this leaves out both Parser.zig files and Vaxis.zig, + // written above. + _ = files.addCopyDirectory(vaxis_dep.path("src"), "", .{ .exclude_extensions = &.{ "Parser.zig", "Vaxis.zig" } }); vaxis_mod.root_source_file = files.getDirectory().path(b, "main.zig"); } @@ -1580,6 +1634,18 @@ pub fn build(b: *std.Build) void { run_monkey9p.setCwd(b.path(".")); run_monkey9p.has_side_effects = true; b.step("monkey-9p", "random 9P operations checking the documented rules (-- [--seed N]... [--steps M] [--replay F] [--shrink F] [--no-shrink])").dependOn(&run_monkey9p.step); + // The GUI's effects under random input in a hidden test window, each + // Motion x Lift x Bloom (test/gui_monkey.py): a gate, not part of + // fs-test, since it needs a Wayland display. + const monkey_gui_step = b.step("monkey-gui", "random input to hidden GUI test windows across the effect settings (-Dplatform=gui; -- [--seed N] [--steps M])"); + if (platform == .gui) { + const run_monkey_gui = b.addSystemCommand(&.{ "python3", "-B", "test/gui_monkey.py" }); + run_monkey_gui.addArtifactArg(exe); + if (b.args) |args| run_monkey_gui.addArgs(args); + run_monkey_gui.setCwd(b.path(".")); + run_monkey_gui.has_side_effects = true; + monkey_gui_step.dependOn(&run_monkey_gui.step); + } else monkey_gui_step.dependOn(&b.addFail("monkey-gui needs -Dplatform=gui").step); const run_monkey9p_smoke = b.addSystemCommand(&.{ "python3", "-B", "test/monkey9p.py" }); run_monkey9p_smoke.addArtifactArg(exe); run_monkey9p_smoke.addArg("--smoke"); |
