Style: themes
lib/style/tui_style.sh, lib/tui_api.sh - resolves theme.css (.class, :focus, :hover, :border, :title, :checked, :unchecked) to fg/bg/mods per pane and widget. Guide: ../guide/markup.md. ← API index for the full module list and a task-oriented tour with examples.
STATE is one of normal (default), focus, border, title, hover, checked, unchecked (the last two for checkboxes); a state without rules falls back to normal. Colors are black red green yellow blue magenta cyan white default, br_black … br_white, or #rrggbb. Functions return 0 unless their entry says otherwise.
Functions that print (tui.ansi, tui.paint, …) need a subshell when captured. In code that runs every frame use the ones that set variables (tui.style.sgr, tui.class.sgr, tui.class.style, tui.class.names).
Styling and themes
| Function | Summary |
|---|---|
tui.load_theme |
Loads a stylesheet into the class table. <theme src="…"/> calls it. |
tui.class |
Applies a theme class to a widget or pane: its normal rules and every pseudo-state it defines (:focus, :border, :title, :hover, :checked, :unchecked). |
tui.style |
Sets the style of a widget or pane directly, without a theme class. |
tui.ansi |
Prints the ANSI escape prefix of a widget or pane style (no reset). A state without rules falls back to normal. |
tui.class.ansi |
Prints the ANSI escape prefix of a theme class, without a widget. |
tui.paint |
Prints TEXT in the style of a widget or pane, followed by a reset. No newline. |
tui.class.paint |
Prints TEXT in the style of a theme class, followed by a reset. No newline. |
tui.style.sgr |
Resolves the style of a widget or pane into variables, without a subshell. |
tui.class.style |
Resolves a theme class into variables, without a subshell. Sets TUI_FG, TUI_BG, TUI_MODS. |
tui.class.sgr |
Resolves a theme class into an escape prefix, without a subshell. |
tui.class.names |
Stores every class and pseudo-state key of the loaded theme, sorted, in the array TUI_CLASSES. Fork-free. |
tui.cache.theme_clear |
Forgets every memoized stylesheet, so the next load parses the files again. |
tui.load_theme
tui.load_theme FILE
Loads a stylesheet into the class table. <theme src="…"/> calls it.
Returns: 1 and a message on stderr when FILE can’t be read or parsed.
Notes
- Rules merge into one table: a later file overrides the fields it sets, and nothing is removed. Classes from a theme loaded on an earlier page stay defined.
- Each file is parsed once per process and re-applied from memory until its mtime changes.
- The app-wide overlay from
tui.theme.setis re-applied after every stylesheet, so it always wins. - Widgets already styled with
tui.classkeep their old colors; load themes before applying classes. - Class names that collide with a widget or pane style are logged as warnings.
See also: tui.class
tui.class
tui.class ID CLASS
Applies a theme class to a widget or pane: its normal rules and every pseudo-state it defines (:focus, :border, :title, :hover, :checked, :unchecked).
Parameters
CLASS: class name without the dot. Empty does nothing.
Notes
- Copies the class’s current values. Changing or reloading the theme afterwards does not restyle
ID; reloading the page does. - Several calls layer: a later class overrides only the fields it sets.
class="…"in markup calls this.
Example
tui.class btn_go nav_link
tui.style
tui.style ID FG BG MODS [STATE]
Sets the style of a widget or pane directly, without a theme class.
Parameters
FG,BG:black red green yellow blue magenta cyan white default, the bright variantsbr_black…br_white, or#rrggbb.""leaves the field unchanged.MODS: space-separated, frombold dim italic underline blink reverse hidden strike.""leaves it unchanged.STATE:normal(default),focus,border,title,hover,checked,unchecked.
Notes
- A field can’t be cleared once set; set it to another value instead.
Example
tui.style status "" "#1e1e2e" bold
tui.style status yellow "" "" border
tui.ansi
tui.ansi ID [STATE]
Prints the ANSI escape prefix of a widget or pane style (no reset). A state without rules falls back to normal.
Notes
- Runs in a subshell when used as
$(tui.ansi ...); in loops prefertui.style.sgr.
tui.class.ansi
tui.class.ansi CLASS [STATE]
Prints the ANSI escape prefix of a theme class, without a widget.
Notes
- Fork-free alternative:
tui.class.sgr.
tui.paint
tui.paint ID TEXT [STATE]
Prints TEXT in the style of a widget or pane, followed by a reset. No newline.
Example
tui.output log "$(tui.paint log "ERROR" title) disk full"
tui.class.paint
tui.class.paint CLASS TEXT [STATE]
Prints TEXT in the style of a theme class, followed by a reset. No newline.
tui.style.sgr
tui.style.sgr ID [STATE]
Resolves the style of a widget or pane into variables, without a subshell.
Sets: TUI_SGR (escape prefix), TUI_FG, TUI_BG. TUI_RESET always holds \e[0m.
Example
tui.style.sgr log title
tui.output_append log "${TUI_SGR}== section ==${TUI_RESET}"
tui.class.style
tui.class.style CLASS [STATE]
Resolves a theme class into variables, without a subshell. Sets TUI_FG, TUI_BG, TUI_MODS.
Notes
- A state the class does not define falls back to the plain class.
tui.class.sgr
tui.class.sgr CLASS [STATE]
Resolves a theme class into an escape prefix, without a subshell.
Sets: TUI_SGR, plus TUI_FG, TUI_BG, TUI_MODS.
Example
tui.class.sgr nav_link focus
printf '%s text%s' "$TUI_SGR" "$TUI_RESET"
tui.class.names
tui.class.names
Stores every class and pseudo-state key of the loaded theme, sorted, in the array TUI_CLASSES. Fork-free.
Notes
- Pseudo-states appear as
CLASS_focus,CLASS_hover, …
tui.cache.theme_clear
tui.cache.theme_clear
Forgets every memoized stylesheet, so the next load parses the files again.
Notes
- Only needed when a file changed without a new mtime; normally edits are picked up automatically.
App-wide theme overlay
| Function | Summary |
|---|---|
tui.theme.set |
Sets an app-wide stylesheet that is layered over every page’s own theme, and reloads the current page. |
tui.theme.clear |
Removes the app-wide stylesheet and reloads the current page. |
tui.theme.current |
Prints the path of the app-wide stylesheet (empty when none). |
tui.theme.reload |
Reloads the current page, keeping focus and cursor when the focused widget still exists. |
tui.theme.set
tui.theme.set FILE
Sets an app-wide stylesheet that is layered over every page’s own theme, and reloads the current page.
Notes
- Lasts for this run only. To keep it across restarts, also
tui.config.set theme FILE(the Settings page does both). - The reload runs the page’s
on_visitagain.
Example
tui.theme.set "$APP/themes/ocean.css"
See also: tui.theme.clear
tui.theme.clear
tui.theme.clear
Removes the app-wide stylesheet and reloads the current page.
Notes
- Classes the overlay defined stay in the class table until they are overridden, because rules are merged, not replaced.
tui.theme.current
tui.theme.current
Prints the path of the app-wide stylesheet (empty when none).
tui.theme.reload
tui.theme.reload
Reloads the current page, keeping focus and cursor when the focused widget still exists.
