Commit 63bd0fe58e

Andrew Kelley <andrew@ziglang.org>
2023-03-14 19:41:37
use DEC graphics instead of Unicode for box drawing
1 parent 3e328c8
Changed files (2)
lib/std/debug.zig
@@ -685,6 +685,36 @@ pub const TTY = struct {
                 },
             };
         }
+
+        pub fn writeDEC(conf: Config, writer: anytype, codepoint: u8) !void {
+            const bytes = switch (conf) {
+                .no_color, .windows_api => switch (codepoint) {
+                    0x50...0x5e => @as(*const [1]u8, &codepoint),
+                    0x6a => "+", // ┘
+                    0x6b => "+", // ┐
+                    0x6c => "+", // ┌
+                    0x6d => "+", // └
+                    0x6e => "+", // ┼
+                    0x71 => "-", // ─
+                    0x74 => "+", // ├
+                    0x75 => "+", // ┤
+                    0x76 => "+", // ┴
+                    0x77 => "+", // ┬
+                    0x78 => "|", // │
+                    else => " ", // TODO
+                },
+                .escape_codes => switch (codepoint) {
+                    // Here we avoid writing the DEC beginning sequence and
+                    // ending sequence in separate syscalls by putting the
+                    // beginning and ending sequence into the same string
+                    // literals, to prevent terminals ending up in bad states
+                    // in case a crash happens between syscalls.
+                    inline 0x50...0x7f => |x| "\x1B\x28\x30" ++ [1]u8{x} ++ "\x1B\x28\x42",
+                    else => unreachable,
+                },
+            };
+            return writer.writeAll(bytes);
+        }
     };
 };
 
lib/build_runner.zig
@@ -532,14 +532,17 @@ const PrintNode = struct {
     last: bool = false,
 };
 
-fn printPrefix(node: *PrintNode, stderr: std.fs.File) !void {
+fn printPrefix(node: *PrintNode, stderr: std.fs.File, ttyconf: std.debug.TTY.Config) !void {
     const parent = node.parent orelse return;
     if (parent.parent == null) return;
-    try printPrefix(parent, stderr);
+    try printPrefix(parent, stderr, ttyconf);
     if (parent.last) {
         try stderr.writeAll("   ");
     } else {
-        try stderr.writeAll("│  ");
+        try stderr.writeAll(switch (ttyconf) {
+            .no_color, .windows_api => "|  ",
+            .escape_codes => "\x1B\x28\x30\x78\x1B\x28\x42  ", // │
+        });
     }
 }
 
@@ -552,14 +555,20 @@ fn printTreeStep(
     step_stack: *std.AutoArrayHashMapUnmanaged(*Step, void),
 ) !void {
     const first = step_stack.swapRemove(s);
-    try printPrefix(parent_node, stderr);
+    try printPrefix(parent_node, stderr, ttyconf);
 
     if (!first) try ttyconf.setColor(stderr, .Dim);
     if (parent_node.parent != null) {
         if (parent_node.last) {
-            try stderr.writeAll("└─ ");
+            try stderr.writeAll(switch (ttyconf) {
+                .no_color, .windows_api => "+- ",
+                .escape_codes => "\x1B\x28\x30\x6d\x71\x1B\x28\x42 ", // └─
+            });
         } else {
-            try stderr.writeAll("├─ ");
+            try stderr.writeAll(switch (ttyconf) {
+                .no_color, .windows_api => "+- ",
+                .escape_codes => "\x1B\x28\x30\x74\x71\x1B\x28\x42 ", // ├─
+            });
         }
     }