class

Scroll::Progress

Inherits Reference < Object

The progress line drawn under the tail when --progress is on.

Two shapes, chosen by whether the input size is known:

unknown:  1.2M 12K ln 840K/s 1.2K ln/s  NAME
known:     45% ███████░░░ 1.2M/2.6M eta 2m01s 840K/s 12K ln  NAME

Counting happens on the hot path (see Counters), so the numbers are exact even when the display drops chunks; the meter itself only formats.

Constants

ASCII_EMPTY = '-'
ASCII_FILL = '#'
BYTE_BASE = 1024

Bytes scale by 1024, because that is what a byte size means. Counts of things scale by 1000, so a million lines reads as 1.0M and not 977K.

BYTE_UNITS = ["B", "K", "M", "G", "T", "P"] of ::String
COUNT_BASE = 1000
COUNT_UNITS = ["", "K", "M", "G", "T", "P"]
EIGHTHS = ["▏", "▎", "▍", "▌", "▋", "▊", "▉"] of ::String
EMPTY = '░'
FILL = '█'
FILLED_STYLE = "42"

SGR bodies. The bar leans on background colors so the filled part and the track meet with no gap between glyphs.

MINIMUM_BAR = 10
MINIMUM_NAME = 8

Columns a name is worth giving up stats fields for. Below this the name is too clipped to identify anything.

NAME_STYLE = "36"
NEWLINE = '\n'.ord.to_u8
PARTIAL_STYLE = "32;100"
PERCENT_STYLE = "1"
PREFERRED_BAR = 30

Columns the bar wants before the name starts stealing from it, and the floor it will not go below while a name is present.

RATE_WINDOW = 3.seconds

Rates are measured over a trailing window rather than the whole run, so a stalled stream shows a falling rate instead of a stale average.

RESET = "\e[0m"
SCROLL_PAUSE = 1.second
SCROLL_RATE = 2.0

A name too long for its field slides left at this rate, holds at the end, then restarts.

SEPARATOR_STYLE = "2"
SIZE = /\A(\d+(?:\.\d+)?)\s*([kmgtp])?(i?b)?\z/i

A byte size: an integer, or a decimal with a 1024-based suffix. Case insensitive, and an "i" and/or "b" may trail the suffix letter (1.5k, 1.5K, 1.5KB, 1.5KiB are the same size).

TRACK_STYLE = "100"

Constructors

new(total : Total, name : String | Nil = nil, started_at : Time::Instant = Time.instant, color : Bool = false, charset : Charset = Charset::Unicode)
Source

Class methods

bar(width : Int32, done : Float64, color : Bool = false, charset : Charset = Charset::Unicode) : String

A bar width columns wide, done of it filled.

With color the filled part and the track are background colors, so they meet with no gap, and a unicode charset gives the leading cell one of the eighth-blocks for sub-column resolution. Without color there is no background to lean on and the bar falls back to glyphs.

Source
duration(span : Time::Span) : String

45s, 2m01s, 1h02m, 3d04h.

Source
human_bytes(value : Int64) : String

1024-based, at most one decimal: 512B, 1.2K, 12K, 1.2M.

Source
human_count(value : Int64) : String

The same shape, 1000-based and without the unit letter at the bottom: 512, 1.2K, 12K.

Source
parse_size(value : String) : Int64
Source
resolve(size : Int64 | Nil, size_lines : Int64 | Nil, file_size : Int64 | Nil) : Tuple(Total, Array(String))

Fold the three size options into one total. A byte size always wins over a line count, and --size over --file-size; each loser is reported so the caller can warn about the option it ignored.

Source
sanitize(text : String) : String

Strip the control bytes a name could otherwise smuggle into the display.

Source
scroll(name : String, width : Int32, elapsed : Time::Span) : String

The window of name visible in a field width columns wide. A name that fits is returned whole; a longer one slides left at SCROLL_RATE columns per second, holds SCROLL_PAUSE at the end, then starts over.

Source

Instance methods

fraction(bytes : Int64, lines : Int64) : Float64 | Nil

How much of the input is done, or nil when the size is unknown. Public because the terminal's own indicator is driven from the same number.

Source
render(width : Int32, bytes : Int64, lines : Int64, now : Time::Instant = Time.instant) : String

The whole line, at most width columns.

Source

Nested types