halo · nim · ~400 loc
ascii progress bars.
one binary.
library and cli in the same file. works in your nim code, works as a pipe in your shell. terminal from stdlib is all it needs. tqdm-ish without pulling in anything.
$ halo --bar 100 -- sh -c 'for i in $(seq 1 100); do sleep 0.02; done' [███████████▓░░░░░░░░] 55% 55/100 eta 0m01s
library
drop it in nim code.
import halo, std/os var bar = newBar(total = 1000, width = 40) for i in 0 ..< 1000: bar.update(i + 1, msg = "step " & $i) sleep(2) bar.finish() var spin = newSpinner(frames = brailleFrames) spin.start("loading") doSomeWork() spin.succeed("done")
bar styles: bsSolid bsDots bsArrows bsBraille bsAscii. spinner frames live in glyphs.nim. the spinner is a ref because it owns a worker thread; succeed / fail / stop joins it and prints one final line.
cli
three ways to use it.
bar around a command
$ halo --bar 100 -- ./longjob
spinner while you wait
$ halo --spin "installing" -- npm install
pass-through pipe counter
$ cat big.csv | halo --pipe --label "parsing" > out
good defaults
- non-tty output (pipe, file, ci logs) falls back to plain lines. no escape codes leak.
- sigint restores the cursor before exiting. exit code is 130.
NO_COLOR=1is honored in--color auto.- spinner interval has a 20ms floor so you don't pin a cpu at zero.
threaded spinner is gc:arc-friendly. haven't stress-tested nested spinners, probably don't. windows ansi works in recent terminals. older cmd.exe untested.
install
$ nimble install halo # or clone and nimble install from the checkout. # binary drops in ~/.nimble/bin/halo