authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-02-01 09:18:52-05:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-21 12:12:17+02:00
log1bd434fd18e0cb769ca46849dac056a562ce7ce3
tree8e65f447eb22547c4f69fb790f05a2fd77fd31e5
parent840331ee48e54b1ce4a3c8196f90eec73ce6deea

std.Progress: improve support for "dumb" terminals


3 files changed, 23 insertions(+), 3 deletions(-)

lib/std/Progress.zig+17-1
...@@ -25,6 +25,13 @@ terminal: ?std.fs.File = undefined,...@@ -25,6 +25,13 @@ terminal: ?std.fs.File = undefined,
25/// Whether the terminal supports ANSI escape codes.25/// Whether the terminal supports ANSI escape codes.
26supports_ansi_escape_codes: bool = false,26supports_ansi_escape_codes: bool = false,
2727
28/// If the terminal is "dumb", don't print output.
29/// This can be useful if you don't want to print all
30/// the stages of code generation if there are a lot.
31/// You should not use it if the user should see output
32/// for example showing the user what tests run.
33dont_print_on_dumb: bool = false,
34
28root: Node = undefined,35root: Node = undefined,
2936
30/// Keeps track of how much time has passed since the beginning.37/// 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) !*...@@ -141,6 +148,9 @@ pub fn start(self: *Progress, name: []const u8, estimated_total_items: usize) !*
141 self.supports_ansi_escape_codes = true;148 self.supports_ansi_escape_codes = true;
142 } else if (std.builtin.os.tag == .windows and stderr.isTty()) {149 } else if (std.builtin.os.tag == .windows and stderr.isTty()) {
143 self.terminal = stderr;150 self.terminal = stderr;
151 } else if (std.builtin.os.tag != .windows) {
152 // we are in a "dumb" terminal like in acme or writing to a file
153 self.terminal = stderr;
144 }154 }
145 self.root = Node{155 self.root = Node{
146 .context = self,156 .context = self,
...@@ -178,6 +188,8 @@ pub fn refresh(self: *Progress) void {...@@ -178,6 +188,8 @@ pub fn refresh(self: *Progress) void {
178}188}
179189
180fn refreshWithHeldLock(self: *Progress) void {190fn refreshWithHeldLock(self: *Progress) void {
191 const is_dumb = !self.supports_ansi_escape_codes and !(std.builtin.os.tag == .windows);
192 if (is_dumb and self.dont_print_on_dumb) return;
181 const file = self.terminal orelse return;193 const file = self.terminal orelse return;
182194
183 const prev_columns_written = self.columns_written;195 const prev_columns_written = self.columns_written;
...@@ -226,7 +238,11 @@ fn refreshWithHeldLock(self: *Progress) void {...@@ -226,7 +238,11 @@ fn refreshWithHeldLock(self: *Progress) void {
226238
227 if (windows.kernel32.SetConsoleCursorPosition(file.handle, cursor_pos) != windows.TRUE)239 if (windows.kernel32.SetConsoleCursorPosition(file.handle, cursor_pos) != windows.TRUE)
228 unreachable;240 unreachable;
229 } else unreachable;241 } else {
242 // we are in a "dumb" terminal like in acme or writing to a file
243 self.output_buffer[end] = '\n';
244 end += 1;
245 }
230246
231 self.columns_written = 0;247 self.columns_written = 0;
232 }248 }
src/Compilation.zig+3-1
...@@ -1538,7 +1538,9 @@ pub fn getCompileLogOutput(self: *Compilation) []const u8 {...@@ -1538,7 +1538,9 @@ pub fn getCompileLogOutput(self: *Compilation) []const u8 {
1538}1538}
15391539
1540pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemory }!void {1540pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemory }!void {
1541 var progress: std.Progress = .{};1541 // If the terminal is dumb, we dont want to show the user all the
1542 // output.
1543 var progress: std.Progress = .{ .dont_print_on_dumb = true };
1542 var main_progress_node = try progress.start("", 0);1544 var main_progress_node = try progress.start("", 0);
1543 defer main_progress_node.end();1545 defer main_progress_node.end();
1544 if (self.color == .off) progress.terminal = null;1546 if (self.color == .off) progress.terminal = null;
src/stage1.zig+3-1
...@@ -278,7 +278,9 @@ export fn stage2_attach_segfault_handler() void {...@@ -278,7 +278,9 @@ export fn stage2_attach_segfault_handler() void {
278// ABI warning278// ABI warning
279export fn stage2_progress_create() *std.Progress {279export fn stage2_progress_create() *std.Progress {
280 const ptr = std.heap.c_allocator.create(std.Progress) catch @panic("out of memory");280 const ptr = std.heap.c_allocator.create(std.Progress) catch @panic("out of memory");
281 ptr.* = std.Progress{};281 // If the terminal is dumb, we dont want to show the user all the
282 // output.
283 ptr.* = std.Progress{ .dont_print_on_dumb = true };
282 return ptr;284 return ptr;
283}285}
284286