etui/style
Types
Terminal color. Default defers to the terminal theme.
Indexed(n) covers the whole 256-color space: 0 to 15 are the themeable
ANSI colors, 16 to 255 the extended palette (the 6x6x6 cube and the
grayscale ramp).
Rgb(r, g, b) uses 24-bit true color and needs a truecolor terminal.
pub type Color {
Default
Indexed(Int)
Rgb(Int, Int, Int)
}
Constructors
-
Default -
Indexed(Int) -
Rgb(Int, Int, Int)
Opaque bitfield for text modifiers. Use constants + add/remove/has.
pub opaque type Modifier
Combined foreground color, background color, text modifiers, and the colour the underline itself is drawn in.
A style carries modifiers it turns on (modifier) and modifiers it turns
off (sub_modifier). The second exists so a style can be laid over
another and take something away: a theme that sets bold everywhere and one
widget that must not be bold is otherwise impossible to express, because an
empty modifier in the overlay means “change nothing”, not “clear”.
underline_color is independent of fg: a spell-checker underlines in red
under text that stays its own colour. It only shows with the underline
modifier on, and only on terminals that implement SGR 58 (kitty, VTE,
WezTerm, iTerm2); the rest ignore the sequence and draw the underline in
the foreground colour, which is the pre-2.0 behaviour.
Build with add_modifier and remove_modifier rather than setting the two
modifier fields directly; they keep the pair consistent.
pub type Style {
Style(
fg: Color,
bg: Color,
modifier: Modifier,
sub_modifier: Modifier,
underline_color: Color,
)
}
Constructors
Values
pub fn add_modifier(s: Style, m: Modifier) -> Style
Turn modifiers on. Anything named here stops being turned off.
pub fn ansi_modifier(m: Modifier) -> String
Text modifier escape sequence. Emits all active modifier bits.
pub fn ansi_underline_color(color: Color) -> String
Underline colour escape sequence (SGR 58).
Colon-separated, which is not a style choice. A terminal that does not
implement 58 must be able to ignore the whole thing, and with semicolons
it cannot: ESC[58;5;9m reads as three ordinary parameters — 58 unknown,
then 5, then 9 — so asking for a red underline made the text blink and
struck it through, and asking for a green one (58;5;2) made it blink and
go dim. Sub-parameters after a colon belong to the parameter they follow,
so ESC[58:5:9m is one attribute a terminal either knows or skips.
The empty field in the RGB form is the colour-space id, which T.416 puts there and every implementation leaves empty.
Default emits nothing rather than SGR 59: a cell is always written after
a reset, so there is no stale underline colour to clear.
pub fn color_from_hex(hex: String) -> Result(Color, Nil)
Parse an RGB color from a hex string ("#RRGGBB" or "RRGGBB").
Returns Error(Nil) for malformed input.
style.color_from_hex("#1e1e2e") // Ok(Rgb(30, 30, 46))
style.color_from_hex("ff5555") // Ok(Rgb(255, 85, 85))
pub fn hidden() -> Modifier
Hidden text: the terminal reserves the cells but draws nothing (SGR 8). Useful for password fields that must keep their layout.
pub fn new(fg: Color, bg: Color, modifier: Modifier) -> Style
A style from the three things most call sites have on hand.
sub_modifier is empty and the underline takes the foreground colour;
reach for remove_modifier and with_underline_color for those.
pub fn patch(base: Style, over: Style) -> Style
Apply over on top of base.
Default colours in over fall through to base. Modifiers that over
turns on are added, and modifiers it turns off are taken away, so an
overlay can clear something the base had set:
let theme = style.default_style() |> style.add_modifier(style.bold())
let quiet = style.default_style() |> style.remove_modifier(style.bold())
style.patch(theme, quiet) // not bold
pub fn rapid_blink() -> Modifier
Rapid blink (SGR 6). Support is rarer than blink, which is SGR 5; a
terminal that does not know it usually falls back to the slow one.
pub fn remove_modifier(s: Style, m: Modifier) -> Style
Turn modifiers off, including ones a style underneath had turned on. Anything named here stops being turned on.
pub fn resolve(s: Style) -> Style
Settle a style into what a cell actually shows: modifiers it turns off win
over modifiers it turns on, and sub_modifier is spent.
Cells hold resolved styles. Two cells that look identical must compare
equal, or the diff repaints them every frame; an unspent sub_modifier
riding along on a cell would break exactly that.