Skip to content

AnsiUtils

Category: Rendering

Source: ansi_utils.dart

Functions

Wrap [text] in an OSC 8 terminal hyperlink pointing to [url].

Modern terminals (iTerm2, Ghostty, Kitty, WezTerm, Windows Terminal) render this as a clickable link. Terminals that don't support OSC 8 simply show the visible text — graceful degradation.

Empty [url] returns the plain display text; this avoids emitting an empty OSC-8 envelope (\x1b]8;;\x07…\x1b]8;;\x07) that some terminals would render as a visible artifact.

Protocol: \x1b]8;;URL\x07VISIBLE_TEXT\x1b]8;;\x07

Wrap [path] in an OSC 8 file hyperlink using an absolute file URI while preserving [text] (or the original path) as the visible label.

String linkifyUrls(String text)

Convert bare http/https URLs in [text] into OSC 8 hyperlinks.

String stripAnsi(String text)

Strip all ANSI escape sequences from [text], including CSI sequences and OSC sequences (e.g. hyperlinks).

int visibleLength(String text)

Compute the visible column width of [text] in a terminal, accounting for ANSI escapes, wide characters (emoji, CJK), and zero-width characters (combining marks, variation selectors).

String ansiTruncate(String text, int maxVisible)

Truncate [text] to [maxVisible] visible columns, preserving ANSI sequences (both CSI and OSC) and handling wide characters. Appends '…' if truncated.

String ansiWrap(String text, int maxWidth)

Word-wrap [text] to fit within [maxWidth] visible columns. Preserves ANSI sequences and existing newlines.

ansiWrap("The quick brown fox jumped over the lazy dog", 20)
→  The quick brown fox
jumped over the
lazy dog

`String wrapIndented(

String text, int width, { String firstPrefix = '', String nextPrefix = '', })`

Word-wrap [text] to [width] visible columns, prepending [firstPrefix] to the first line and [nextPrefix] to continuation lines.

Unlike [ansiWrap] which only breaks long lines, this also handles prefixed/indented content where continuation lines need alignment.

// Plain indentation (firstPrefix & nextPrefix = '   '):
wrapIndented("The quick brown fox jumped", 20,
firstPrefix: '   ', nextPrefix: '   ')
→     The quick brown
fox jumped

// List bullet (firstPrefix = '• ', nextPrefix = '  '):
wrapIndented("The quick brown fox jumped", 20,
firstPrefix: '• ', nextPrefix: '  ')
→  • The quick brown
fox jumped

// Blockquote (firstPrefix & nextPrefix = '│ '):
wrapIndented("The quick brown fox jumped", 20,
firstPrefix: '│ ', nextPrefix: '│ ')
→  │ The quick brown
│ fox jumped

String applySelectionHighlight(String line, int startCol, int endCol)

Wrap visible columns [startCol, endCol) of an ANSI-styled [line] with reverse-video (\x1b[7m / \x1b[27m), preserving existing CSI and OSC sequences and treating wide glyphs as 2 cells.

Used to paint the transcript-selection highlight onto the visible viewport slice without forcing every renderer downstream to know anything about selections.

Columns count display cells: a CJK or emoji glyph occupies 2 cells. If [startCol] falls inside a wide glyph the entire glyph is included; likewise for [endCol]. Out-of-range bounds clamp to the line's visible width. Returns [line] unchanged if endCol <= startCol.

int charWidth(int cp)

Terminal column width of a single Unicode code point.

Released under the MIT License.