Skip to content

progress

Terminal progress bars and spinners.

Progress state is implicit: with activates a progress context for the current scope, and show creates widgets at the appropriate nesting depth automatically.

When term.console is a terminal, indicators are shown below console output lines from term.echo, term.print, child process output, etc.

When term.console is not a terminal, indicators produce interleaved log message instead. Routine progress updates are rate-limited, while changes to an indicator's icon or message are printed immediately. Indicator creation and completion are always logged.

Types

TypeDescription
Indicator A progress bar or spinner.
Attr A text attribute for Colors.
Color A color for Colors.
Colors Colors and attributes of one element of the progress display.
Style Display style overrides for with.
Units Display units of an indicator.

Attr = (:BOLD: | :DIM: | :ITALIC: | :UNDERLINED: | :BLINK: | :REVERSE: | :HIDDEN: | :STRIKETHROUGH:)

A text attribute for Colors.

Attribute Effect
:BOLD: Bold
:DIM: Dim
:ITALIC: Italic
:UNDERLINED: Underlined
:BLINK: Blinking
:REVERSE: Reverse video
:HIDDEN: Hidden
:STRIKETHROUGH: Strikethrough

Color = (:BLACK: | :RED: | :GREEN: | :YELLOW: | :BLUE: | :MAGENTA: | :CYAN: | :WHITE: | :BRIGHT_BLACK: | :BRIGHT_RED: | :BRIGHT_GREEN: | :BRIGHT_YELLOW: | :BRIGHT_BLUE: | :BRIGHT_MAGENTA: | :BRIGHT_CYAN: | :BRIGHT_WHITE: | :BRIGHT:)

A color for Colors.

Standard Bright
:BLACK: :BRIGHT_BLACK:
:RED: :BRIGHT_RED:
:GREEN: :BRIGHT_GREEN:
:YELLOW: :BRIGHT_YELLOW:
:BLUE: :BRIGHT_BLUE:
:MAGENTA: :BRIGHT_MAGENTA:
:CYAN: :BRIGHT_CYAN:
:WHITE: :BRIGHT_WHITE:

:BRIGHT: brightens the default color.

Colors = {?fg: Color, ?bg: Color, ?attrs: Array[Attr]}

Colors and attributes of one element of the progress display.

Key Meaning
fg Foreground color
bg Background color
attrs Text attributes

Style = Dict[{?bar: Dict[{?width: Int, ...Colors, ?alt: Dict[Colors]}], ?message: Dict[{?width: Int, ...Colors}], ?icon: Dict[{?width: Int, ...Colors}], ?status: Dict[{?width: Int}], ?spinner: Dict[Colors], ?elapsed: Dict[Colors], ?position: Dict[Colors], ?total: Dict[Colors]}]

Display style overrides for with.

Each key names an element of the progress display. bar, message, icon and status take a width in characters; every element but status takes Colors. bar also takes alt, the colors of its unfilled portion. Omitted values use these defaults:

Element Default width Default fg Default attrs
bar 20 :CYAN:
bar.alt :BLUE:
message 40 :BOLD:
icon 2 :BOLD:
status 30
spinner :CYAN:
elapsed :DIM:
position
total

Units = (:COUNT: | :BYTES: | :PERCENT:)

Display units of an indicator.

Value Description
:COUNT: Display as pos/len or pos
:BYTES: Display as human-readable bytes
:PERCENT: Display pos / len as a percentage

Functions

show[R] func … -> R

Creates a progress indicator and runs func with it.

The indicator is removed when func returns. Called inside another indicator's scope, the new indicator appears indented beneath the parent widget.

Outside a with scope, the callback is invoked with a dummy indicator whose methods are silent no-ops.

Parameters

NameTypeDescription
:total? Int Total value. The indicator starts in bar mode when given and in spinner mode otherwise; the mode changes with total.
:message? Str Initial message.
:icon? Str Prefix icon, such as "📦".
:units? Units Unit format.
:tick? Float Tick interval in seconds. Defaults to 0.08.
func ((Indicator) -> R) Callback receiving an Indicator.
:units

Units default to :COUNT: when total is given. With neither total nor units, spinner mode shows only elapsed time.

Example

progress.with do
  progress.show total: 3 message: "building" do |w|
    progress.show message: "step 1" do |_|
      do_step_1()
    w.delta()

The Indicator is only valid inside its callback. Using it after the callback returns raises a runtime error.

steps *steps … -> Array[Value]

Runs a sequence of steps under an indicator tracking step completion.

Before a named step runs, its name is appended to the overall message with a colon, such as building: compile. An unnamed step uses the overall message unchanged. If there is no overall message, a named step uses its name by itself.

If a step raises an error, the remaining steps are skipped and the error is propagated.

Parameters

NameTypeDescription
:message? Str Overall message prefix.
:icon? Str Default icon. Defaults to "●".
*steps ((() -> Value) | Dict[{() -> Value, ?name: Str, ?icon: Str}]) A step function or specification.
*steps

A specification contains one positional function and accepts these keys:

Key Type Description
name Str Step name
icon Str Icon overriding the default

Returns

Each step's return value, in order.

Example

let results = progress.steps message: building icon: ""
  - name: compile
    icon: "C"
    do compile()
  do test()
  - name: package
    do package()

with[R] func … -> R

Activates a progress context for the duration of func.

Terminal output — echo, print, and child process stdout/stderr — is routed through the progress display so that it does not interfere with active indicators.

Inside an active context, with runs func in that context, so a script that sets up its own progress display can run nested in another one. Its indicators nest beneath the enclosing indicator, and style and interval are ignored after they are checked.

Parameters

NameTypeDescription
:style? Style Display style overrides.
:interval? Float Plain-mode rate limit in seconds. Defaults to 5. Has no effect when connected to a real terminal.
func (() -> R) Callback taking no arguments.

Example

progress.with do
  progress.show total: 100 message: "downloading" do |w|
    for i = Range 100
      w.delta()

# With custom style
progress.with
  style:
    bar:
      width: 30
      fg: :GREEN:
      alt:
        fg: :BLACK:
        attrs:
          - :DIM:
    message:
      fg: :WHITE:
      attrs:
        - :BOLD:
    position:
      fg: :YELLOW:
  do progress.show message: "working" do |w|
    # ...