summaryrefslogtreecommitdiff
path: root/build.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 18:40:43 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:17 -0300
commite29faca73e07eb90aa0c8f6f33e55c8ace77a3c4 (patch)
tree880665174b4f097b7279aa0d059ecbe43e64c6f3 /build.zig
parentb8b9e87972f87abd28c5bebf7275e9bdd2754eac (diff)
downloadpardes-e29faca73e07eb90aa0c8f6f33e55c8ace77a3c4.tar.gz
pardes-e29faca73e07eb90aa0c8f6f33e55c8ace77a3c4.zip
A blank whose ink alone changed is skipped in vaxis's own frame diff, not weighed up per cell in the tty
Diffstat (limited to 'build.zig')
-rw-r--r--build.zig52
1 files changed, 50 insertions, 2 deletions
diff --git a/build.zig b/build.zig
index 8646be05..2419dd59 100644
--- a/build.zig
+++ b/build.zig
@@ -864,11 +864,59 @@ 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");
+ 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");
}