From 1bd434fd18e0cb769ca46849dac056a562ce7ce3 Mon Sep 17 00:00:00 2001 From: jacob gw Date: Mon, 1 Feb 2021 09:18:52 -0500 Subject: [PATCH] std.Progress: improve support for "dumb" terminals --- lib/std/Progress.zig | 18 +++++++++++++++++- src/Compilation.zig | 4 +++- src/stage1.zig | 4 +++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/std/Progress.zig b/lib/std/Progress.zig index 131aff2d2b..4afd191b93 100644 --- a/lib/std/Progress.zig +++ b/lib/std/Progress.zig @@ -25,6 +25,13 @@ terminal: ?std.fs.File = undefined, /// Whether the terminal supports ANSI escape codes. supports_ansi_escape_codes: bool = false, +/// If the terminal is "dumb", don't print output. +/// This can be useful if you don't want to print all +/// the stages of code generation if there are a lot. +/// You should not use it if the user should see output +/// for example showing the user what tests run. +dont_print_on_dumb: bool = false, + root: Node = undefined, /// Keeps track of how much time has passed since the beginning. @@ -141,6 +148,9 @@ pub fn start(self: *Progress, name: []const u8, estimated_total_items: usize) !* self.supports_ansi_escape_codes = true; } else if (std.builtin.os.tag == .windows and stderr.isTty()) { self.terminal = stderr; + } else if (std.builtin.os.tag != .windows) { + // we are in a "dumb" terminal like in acme or writing to a file + self.terminal = stderr; } self.root = Node{ .context = self, @@ -178,6 +188,8 @@ pub fn refresh(self: *Progress) void { } fn refreshWithHeldLock(self: *Progress) void { + const is_dumb = !self.supports_ansi_escape_codes and !(std.builtin.os.tag == .windows); + if (is_dumb and self.dont_print_on_dumb) return; const file = self.terminal orelse return; const prev_columns_written = self.columns_written; @@ -226,7 +238,11 @@ fn refreshWithHeldLock(self: *Progress) void { if (windows.kernel32.SetConsoleCursorPosition(file.handle, cursor_pos) != windows.TRUE) unreachable; - } else unreachable; + } else { + // we are in a "dumb" terminal like in acme or writing to a file + self.output_buffer[end] = '\n'; + end += 1; + } self.columns_written = 0; } diff --git a/src/Compilation.zig b/src/Compilation.zig index ae3385b2dc..180d49a196 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1538,7 +1538,9 @@ pub fn getCompileLogOutput(self: *Compilation) []const u8 { } pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemory }!void { - var progress: std.Progress = .{}; + // If the terminal is dumb, we dont want to show the user all the + // output. + var progress: std.Progress = .{ .dont_print_on_dumb = true }; var main_progress_node = try progress.start("", 0); defer main_progress_node.end(); if (self.color == .off) progress.terminal = null; diff --git a/src/stage1.zig b/src/stage1.zig index 8ab3b1d94d..1b7eadd1a8 100644 --- a/src/stage1.zig +++ b/src/stage1.zig @@ -278,7 +278,9 @@ export fn stage2_attach_segfault_handler() void { // ABI warning export fn stage2_progress_create() *std.Progress { const ptr = std.heap.c_allocator.create(std.Progress) catch @panic("out of memory"); - ptr.* = std.Progress{}; + // If the terminal is dumb, we dont want to show the user all the + // output. + ptr.* = std.Progress{ .dont_print_on_dumb = true }; return ptr; }