diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-05-27 09:48:13 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2024-05-27 20:56:48 -0700 |
| commit | 52ffdec74b5854bc842107f40f9fa31b40cf5432 (patch) | |
| tree | 8fc13b63abe57cfe30e4e4286deb503b9ab0654b /lib/std/Progress.zig | |
| parent | 849693f07c882fad369e557940583b8ac9d1c648 (diff) | |
| download | zig-52ffdec74b5854bc842107f40f9fa31b40cf5432.tar.gz zig-52ffdec74b5854bc842107f40f9fa31b40cf5432.zip | |
std.Progress: keep cursor on newline
Don't truncate trailing newline. This better handles stray writes to
stderr that are not std.Progress-aware, such as from non-zig child
processes.
This commit also makes `Node.start` and `Node.end` bail out early with a
comptime branch when it is known the target will not be spawning an
update thread.
Diffstat (limited to 'lib/std/Progress.zig')
| -rw-r--r-- | lib/std/Progress.zig | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/lib/std/Progress.zig b/lib/std/Progress.zig index 679b44a5db..4a40aed1d2 100644 --- a/lib/std/Progress.zig +++ b/lib/std/Progress.zig @@ -155,6 +155,10 @@ pub const Node = struct { /// /// Passing 0 for `estimated_total_items` means unknown. pub fn start(node: Node, name: []const u8, estimated_total_items: usize) Node { + if (noop_impl) { + assert(node.index == .none); + return .{ .index = .none }; + } const node_index = node.index.unwrap() orelse return .{ .index = .none }; const parent = node_index.toParent(); @@ -208,6 +212,10 @@ pub const Node = struct { /// Finish a started `Node`. Thread-safe. pub fn end(n: Node) void { + if (noop_impl) { + assert(n.index == .none); + return; + } const index = n.index.unwrap() orelse return; const parent_ptr = parentByIndex(index); if (parent_ptr.unwrap()) |parent_index| { @@ -296,6 +304,11 @@ var default_draw_buffer: [4096]u8 = undefined; var debug_start_trace = std.debug.Trace.init; +const noop_impl = builtin.single_threaded or switch (builtin.os.tag) { + .wasi, .freestanding => true, + else => false, +}; + /// Initializes a global Progress instance. /// /// Asserts there is only one global Progress instance. @@ -319,6 +332,9 @@ pub fn start(options: Options) Node { global_progress.refresh_rate_ns = options.refresh_rate_ns; global_progress.initial_delay_ns = options.initial_delay_ns; + if (noop_impl) + return .{ .index = .none }; + if (std.process.parseEnvVarInt("ZIG_PROGRESS", u31, 10)) |ipc_fd| { global_progress.update_thread = std.Thread.spawn(.{}, ipcThreadRun, .{ @as(posix.fd_t, switch (@typeInfo(posix.fd_t)) { @@ -507,7 +523,7 @@ fn computeClear(buf: []u8, start_i: usize) usize { global_progress.newline_count = 0; buf[i] = '\r'; i += 1; - for (1..prev_nl_n) |_| { + for (0..prev_nl_n) |_| { buf[i..][0..up_one_line.len].* = up_one_line.*; i += up_one_line.len; } @@ -841,9 +857,6 @@ fn computeRedraw(serialized_buffer: *Serialized.Buffer) []u8 { const root_node_index: Node.Index = @enumFromInt(0); i = computeNode(buf, i, serialized, children, root_node_index); - // Truncate trailing newline. - if (buf[i - 1] == '\n') i -= 1; - buf[i..][0..finish_sync.len].* = finish_sync.*; i += finish_sync.len; @@ -932,8 +945,10 @@ fn computeNode( } fn withinRowLimit(p: *Progress) bool { - // The +1 here is so that the PS1 is not scrolled off the top of the terminal. - return p.newline_count + 1 < p.rows; + // The +2 here is so that the PS1 is not scrolled off the top of the terminal. + // one because we keep the cursor on the next line + // one more to account for the PS1 + return p.newline_count + 2 < p.rows; } fn write(buf: []const u8) void { |
