progress

progress
git clone git://brookjeynes.dev/bjeynes/progress.git
Log | Files | Refs | README | LICENSE

commit fe3178cf381adf9994cc2151ecb1ad8ebacba2f5
parent be0bea6140acbd2296b9a8e89fe8f2ed281d9158
Author: BrookJeynes <jeynesbrook@gmail.com>
Date:   Mon, 28 Oct 2024 10:20:41 +1000

Progress bar now supports u21 ascii characters
- Updated bar/complex.zig example to showcase this.

Diffstat:
Mexamples/bar/complex.zig | 29+++++++++++++++++++++--------
Msrc/bar.zig | 16++++++++++------
Msrc/spinner.zig | 2++
3 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/examples/bar/complex.zig b/examples/bar/complex.zig @@ -3,24 +3,37 @@ const ProgressBar = @import("progress").Bar; pub fn main() !void { const stdout = std.io.getStdOut().writer(); - var pb = ProgressBar.init(28, stdout.any(), .{ + + var pb1 = ProgressBar.init(28, stdout.any(), .{ .bar_prefix = '[', .bar_suffix = ']', .bar_fill_char = '=', .description = "A complex progress bar", .show_iterations = true, .show_percentage = true, - .write_newline_on_finish = false, .width = 60, }); - defer pb.clear() catch {}; + var pb2 = ProgressBar.init(15, stdout.any(), .{ + .bar_prefix = '|', + .bar_suffix = '|', + .bar_fill_char = '█', + .description = "A second complex progress bar", + .show_iterations = true, + .show_percentage = true, + .width = 100, + }); + const progress_bars: [2]*ProgressBar = .{ &pb1, &pb2 }; - while (!pb.isFinished()) { - pb.add(1); - try pb.render(); + for (progress_bars, 0..) |pb, i| { + while (!pb.isFinished()) { + pb.add(1); + try pb.render(); - if (pb.current_progress == 14) pb.update_description("Half way there"); + if (i == 0) { + if (pb.current_progress == 14) pb.updateDescription("Half way there"); + } - std.time.sleep(std.time.ns_per_ms * 150); + std.time.sleep(std.time.ns_per_ms * 150); + } } } diff --git a/src/bar.zig b/src/bar.zig @@ -15,11 +15,11 @@ const Config = struct { ///Progress bar description. description: ?[]const u8 = null, ///The progress bar prefix. - bar_prefix: u8 = '|', + bar_prefix: u21 = '|', ///The progress bar suffix. - bar_suffix: u8 = '|', + bar_suffix: u21 = '|', ///The charater to fill the progress bar with. - bar_fill_char: u8 = '#', + bar_fill_char: u21 = '#', ///Show the iteration count. show_iterations: bool = false, ///Show the percentage. @@ -70,6 +70,7 @@ pub fn add(self: *Bar, num: usize) void { pub fn render(self: *Bar) !void { const winsize = try termsize.termSize(std.io.getStdOut()) orelse termsize.TermSize{ .width = default_bar_width, .height = 0 }; const width = if (self.config.width) |w| @min(w, winsize.width) else winsize.width; + var unicode_conversion_buf: [8]u8 = undefined; self.mutex.lock(); defer self.mutex.unlock(); @@ -124,17 +125,20 @@ pub fn render(self: *Bar) !void { try escape_codes.cursorForward(self.bw.writer(), 1); } - _ = try self.bw.writer().writeByte(self.config.bar_prefix); + const prefix_bytes = try std.unicode.utf8Encode(self.config.bar_prefix, &unicode_conversion_buf); + _ = try self.bw.write(unicode_conversion_buf[0..prefix_bytes]); const range: usize = @intFromFloat(percentage * @as(f32, @floatFromInt(std.math.sub(usize, width, extra_front_chars + extra_back_chars) catch 0))); for (0..range) |_| { - _ = try self.bw.writer().writeByte(self.config.bar_fill_char); + const fill_char_bytes = try std.unicode.utf8Encode(self.config.bar_fill_char, &unicode_conversion_buf); + _ = try self.bw.write(unicode_conversion_buf[0..fill_char_bytes]); } try escape_codes.hideCursor(self.bw.writer()); try escape_codes.setCursorColumn(self.bw.writer(), width - extra_back_chars); - _ = try self.bw.writer().writeByte(self.config.bar_suffix); + const suffix_bytes = try std.unicode.utf8Encode(self.config.bar_suffix, &unicode_conversion_buf); + _ = try self.bw.write(unicode_conversion_buf[0..suffix_bytes]); if (self.current_progress >= self.max_progress and !self.finished) { self.finished = true; diff --git a/src/spinner.zig b/src/spinner.zig @@ -54,6 +54,8 @@ fn renderComplete(self: *Spinner, completion_char: u21) !void { _ = try self.bw.write(desc); } + if (self.config.clear_on_finish) try self.clear(); + try self.bw.flush(); }