Skip to content

Text

Validated terminal presentation.

Produced by text, by preformat, or by calling a Style.

Nested Text values are flattened when composed, and an ANSI reset code in a nested value restores the enclosing style. Terminal output functions render Text with ANSI styling when the console can style and as plain text otherwise.

Formatting

A format specification applied to Text measures terminal cells rather than extended grapheme clusters, the same measure width() reports: width pads to a cell count, precision clips to one at a cluster boundary, and SGR sequences consume neither.

Formatting produces a Str, so it drops the styling along with every other str conversion: "${label:6}" is laid out in cells and plain.

To keep the styling, pass a FmtValue bound to the Text to echo, print, text or a Style. They lay it out in terminal cells themselves:

let label = text("界a", fg: :RED:)
echo (std.FmtValue label width: 6)     # padded and still red
echo "${label:6}"                      # padded and plain

A specification for a debug or numeric rendering drops the styling and renders the Text like any other value.

Sequences

A "..." string converts its interpolations as it is built, so a Text in one loses its styling. A t"..." keeps them apart, and the output functions render each one separately, so styling survives interpolation at any depth:

let label = text("界a", fg: :RED:)
echo t"tag: ${label:6}|"     # padded in cells and still red
echo "tag: ${label:6}|"      # padded and plain

let framed = t"[${label:^8}]"
echo t"<${framed:>12}>"      # each level lays out what the one inside rendered

Only the output functions expand a sequence this way; converting one to a string still drops the styling. Each segment is rendered as a separate argument would be, so the rules above apply to it unchanged.

A sequence containing a FmtParam hole raises a ValueError.

Example

let label = text ERROR fg: :RED: bold: true
echo $label " request failed"

# Preserve ANSI escapes for a file or another process.
let encoded = label.encode()

Methods

(str)() -> Str

Returns the content with the styling dropped.

The escape sequences are terminal instructions, not content: a Str carrying them counts them in its length, matches them in a search, and writes them into whatever file or pipe it reaches. Ask for them with encode. verbatim reproduces a value as it would have been written in source, and styled text has no source form, so it gives the same content this does.

clip width … -> Text

Clips the text to a terminal-cell width at an extended grapheme boundary.

SGR sequences do not contribute to the width. If the text already fits it is returned unchanged and suffix is ignored. Otherwise the suffix is clipped to the total budget, its width is reserved, and the longest fitting source prefix is prepended. Styling remains valid across the cut.

Parameters

NameTypeDescription
width Int Non-negative terminal-cell budget.
:suffix? (Str | Text) Suffix appended only when truncating.

Example

let warning = text("abcdef", fg: :YELLOW:)
echo $warning.clip(4, suffix: "…")

encode() -> Str

Returns the ANSI representation: exactly the bytes a terminal write emits.

This is the inverse of preformat, which takes the result back (canonicalizing the SGR it re-emits).

Example

let label = text ERROR fg: :RED:
assert_eq (str label) ERROR
fs.write $path $label.encode()

indent spaces -> Text

Adds spaces to the beginning of each line without changing ANSI formatting.

A terminal newline does not gain a trailing indentation prefix.

Parameters

NameTypeDescription
spaces Int Non-negative number of spaces.

Example

let diagnostic = [...unit.diagnostics()][0].render()
echo $diagnostic.indent(4)

join iter -> Text overload 1 of 2

Concatenates values with this text between them.

Each value is taken the way text takes an argument of its own: a Text keeps its styling, and anything else is converted and sanitized.

Parameters

NameTypeDescription
iter Iterable[Value] Values to join.

Example

let sep = text " | " fg: :YELLOW:
echo $sep.join([text("ok", fg: :GREEN:), "then", 3])

join() -> Text overload 2 of 2

Concatenates the values of the strand's input with this text between them.

Parameters

NameTypeDescription
< Iter[Value]

width() -> Int

Returns the visible terminal-cell width of the text.

SGR sequences do not contribute to the width. Widths are summed within each extended grapheme cluster and capped at two cells per cluster. C0 control characters contribute zero.

Example

assert_eq ((text "é").width()) 1
assert_eq ((text "👩‍💻").width()) 2
assert_eq ((text "界").width()) 2