A line can carry more than one colour.
ui.text([
{ text: "ERROR ", fg: theme.danger, bold: true },
{ text: "connection refused" },
]);Added
Span,SpanLineandRichText, plusSurface.spans()for drawing them.- Span-aware measuring, truncation, padding and word wrap:
spanWidth,truncateSpans,fitSpans,wrapSpans,wrapRich,toSpanLines,spanStyle,spanText,isRich. drawTextandui.text/ui.label/ui.headingacceptRichTextwherever they took a string.
Compatibility
A bare string is the one-span case, so no existing call site changes and no committed frame moves. Both fixture generators regenerate byte for byte, and the six native ports stay in parity — they simply do not offer spans yet.
The span layout is held to the exact output of the string functions it mirrors: truncateSpans, fitSpans and wrapSpans produce the same columns as truncate, fit and wrap across a corpus of CJK, emoji, ZWJ sequences, combining marks and overlong tokens at eight widths.
232 tests pass under Bun and Node.