Skip to main content

API reference — style & color

All types live in core.term.style. Guided treatment: styling & themes.

Color​

public type Color is
| Reset
| Black | DarkGrey
| Red | DarkRed
| Green | DarkGreen
| Yellow | DarkYellow
| Blue | DarkBlue
| Magenta | DarkMagenta
| Cyan | DarkCyan
| White | Grey
| Ansi256(Int) // 0..255
| TrueColor(Rgb)
| FromHsl(Hsl); // converted to Rgb at render

The sixteen ANSI colours are variants, not a Base16(Int) index — Color.DarkRed is a constructor, not a constant standing for an index. There is no Lab arm either: Lab is a separate type reached through Rgb.to_lab() for perceptual work, never a colour a terminal is asked to render.

// Common constants
Color.Black Color.DarkRed
Color.DarkGreen Color.DarkYellow
Color.DarkBlue Color.DarkMagenta Color.DarkCyan Color.Grey
Color.DarkGrey Color.Red
Color.Green
Color.Yellow
Color.Blue
Color.Magenta Color.Cyan
Color.White
Rgb.new(r: UInt8, g: UInt8, b: UInt8) -> Rgb
Rgb.from_hex(hex: &Text) -> Maybe<Rgb> // "#RRGGBB" or "RRGGBB"

Hsl.new(h: Float, s: Float, l: Float) -> Hsl // h in [0,360], s/l in [0,1]
Hsl.to_rgb(&self) -> Rgb
Hsl.lighten(&self, f: Float) -> Hsl
Hsl.darken(&self, f: Float) -> Hsl

Style​

public type Style is {
fg: Maybe<Color>,
bg: Maybe<Color>,
underline_color: Maybe<Color>,
add_modifier: Modifier,
sub_modifier: Modifier,
};

The surface:

Style.DEFAULT // all None / empty
Style.new() -> Style
.fg(c: Color) -> Self
.bg(c: Color) -> Self
.underline_color(c: Color) -> Self
.bold() .italic() .dim()
.underlined() .reversed() .crossed_out()
.not_bold() .not_italic() .not_underlined() // the sub_modifier set
.has_modifier(m: Modifier) -> Bool
.patch(other: Style) -> Style // merge; `other` wins
.hyperlink(url: &Text) -> Self

Modifier​

public type Modifier is { bits: UInt16 };
Modifier.NONE
Modifier.BOLD
Modifier.DIM
Modifier.ITALIC
Modifier.UNDERLINED
Modifier.DOUBLE_UNDERLINED Modifier.CURLY_UNDERLINED
Modifier.SLOW_BLINK
Modifier.RAPID_BLINK
Modifier.REVERSED
Modifier.HIDDEN
Modifier.CROSSED_OUT
Modifier.OVERLINED
fn contains(&self, m: Modifier) -> Bool
fn union(&self, m: Modifier)
-> Modifier
fn intersect(&self, m: Modifier) -> Modifier
fn difference(&self, m: Modifier) -> Modifier

Theme​

// Every role is a full `Style`, not a `Color`: a role carries
// foreground, background, underline colour and modifiers together, so a
// theme can say "muted text is dim grey italic" in one field.
public type Theme is {
// Surfaces
surface: Style, surface_dim: Style, on_surface: Style,
// Interactive
primary: Style, on_primary: Style, secondary: Style, on_secondary: Style,
// Semantic
error: Style, warning: Style, success: Style, info: Style,
// Borders
border: Style, border_focused: Style, divider: Style,
// Text emphasis
text: Style, text_dim: Style, text_muted: Style, text_highlight: Style,
// Selection
selection: Style, cursor: Style,
};

There is no surface_alt, muted or accent. The nearest names are surface_dim, text_muted and primary, and the on_* roles say what to draw ON a coloured background — a pairing the three-name palette could not express.

Theme.dark() -> Theme
Theme.light() -> Theme

ColorProfile​

public type ColorProfile is NoColor | Base16 | Ansi256 | TrueColor;

public fn adapt_color(c: Color, profile: ColorProfile) -> Color;

adapt_color uses CIELAB perceptual distance to find the closest representable color in the target profile — the right choice for 16-color fallbacks on otherwise-truecolor inputs.

Text builder DSL​

The span type is TextSpan (core/term/widget/paragraph.vr). A bare Span is a different type entirely — core.meta's macro-hygiene span — and writing it here is not a shorthand.

mount core.term.style.text_builder.*;

bold(t: Text) -> TextSpan
italic(t: Text) -> TextSpan
dim(t: Text) -> TextSpan
underlined(t: Text) -> TextSpan
crossed_out(t: Text) -> TextSpan
reversed(t: Text) -> TextSpan

fg(t: Text, c: Color) -> TextSpan bg(t: Text, c: Color) -> TextSpan
red(t: Text) -> TextSpan green(t: Text) -> TextSpan blue(t: Text) -> TextSpan
yellow(t: Text) -> TextSpan cyan(t: Text) -> TextSpan magenta(t: Text) -> TextSpan
white(t: Text) -> TextSpan grey(t: Text) -> TextSpan
Interpreter style controls

The recorded controls distinguish modifier changes, foreground colour and an unstyled raw span:

bold("x") add_modifier.bits=1 has_fg=false
green("x") add_modifier.bits=0 has_fg=true
TextSpan.raw("x") add_modifier.bits=0 has_fg=false
Modifier.BOLD.bits=1

A helper that resolved and did nothing would give all three the same style. bold sets exactly Modifier.BOLD and no colour, green sets a colour and no modifier, raw sets neither.

Color utilities​

mount core.term.style.color_utils.*;

fn hex(s: &Text) -> Color // panic on parse error
fn hex_gradient(a: &Text, b: &Text, steps: Int) -> List<Rgb>