progress.ha (1466B)
1 use fmt; 2 use io; 3 use math; 4 use unix::tty; 5 6 fn progress_update(plan: *plan) void = { 7 const tty = match (plan.progress.tty) { 8 case let f: io::file => 9 yield f; 10 case => 11 return; 12 }; 13 14 const width = match (tty::winsize(tty)) { 15 case let ts: tty::ttysize => 16 yield if (ts.columns > 80 || ts.columns == 0) 80 else ts.columns; 17 case => 18 yield 64; 19 }: size; 20 21 const complete = plan.progress.complete, 22 total = plan.progress.total, 23 current_module = plan.progress.current_module; 24 25 const total_width = math::ceilf64(math::log10f64(total: f64)): size; 26 const counter_width = 1 + total_width + 1 + total_width + 3; 27 const progress_width = width - counter_width - 2 - plan.progress.maxwidth; 28 29 fmt::fprintf(tty, "\x1b[G\x1b[K[{%}/{}] [", 30 complete, &fmt::modifiers { 31 width = total_width: uint, 32 ... 33 }, 34 total)!; 35 const stop = (complete: f64 / total: f64 * progress_width: f64): size; 36 for (let i = 0z; i < progress_width; i += 1) { 37 if (i > stop) { 38 fmt::fprint(tty, ".")!; 39 } else { 40 fmt::fprint(tty, "#")!; 41 }; 42 }; 43 if (len(current_module) > 0) { 44 fmt::fprintf(tty, "] {}", current_module)!; 45 } else { 46 // Don't print a leading space 47 fmt::fprint(tty, "]")!; 48 }; 49 }; 50 51 fn progress_clear(plan: *plan) void = { 52 const tty = match (plan.progress.tty) { 53 case let f: io::file => 54 yield f; 55 case => 56 return; 57 }; 58 fmt::fprint(tty, "\x1b[G\x1b[K")!; 59 }; 60 61 fn progress_increment(plan: *plan) void = { 62 plan.progress.complete += 1; 63 progress_update(plan); 64 };