Themes and Appearance

Colour themes, custom and imported themes, chrome colours, glyph sets, spacing, dimming and the spotlight.

Four things decide what TUIOS looks like:

PartWhat it controlsHow to set it
ColourThe terminal colours, the accents, the bordersappearance.theme
ShapeThe characters the chrome is drawn with: borders, controls, rules, rail marksappearance.glyphs
SpacingEmpty ground between panes, padding inside dialogsappearance.gap, appearance.panel_padding
TextWhat a window title, a workspace tab and the clock showwindow_title_format, dock_workspace_tab_format, clock_format

Every option on this page can be changed while TUIOS runs, from the settings page (, in window mode), with tuios set-config, or by editing config.toml, which is reloaded when saved.

Try it live: the Make it yours track lets you try themes and glyphs in your browser.

Choosing a theme

On Omarchy, TUIOS uses the Omarchy theme when you set no theme, and changes with it. Added in v0.10.0

TUIOS ships over 300 themes. A theme sets the 16 ANSI colours plus foreground, background and cursor, and TUIOS derives its own interface colours from them.

[appearance]
theme = "catppuccin_mocha"
# Change it in the running session
tuios set-config appearance.theme catppuccin_mocha

# Start with a theme, overriding the config for this run
tuios --theme dracula

# Find one
tuios list-themes --filter gruvbox
tuios --list-themes | fzf --preview 'tuios --preview-theme {}'

Theme ids use underscores: tokyo_night, not tokyo-night.

In the app, open the picker from the palette (Theme picker) or from the Theme row on the settings page. It is searchable, shows a swatch per theme, and applies the selection live as you move. Esc puts back the theme you started with.

The picker applies a theme as you select it. This session also paints the theme ground behind the panes (appearance.background).

Try it here. Each button sets a theme in a live tuios. You can also press Ctrl+P, type theme and press Enter.

Runs the real tuios in this page. It downloads about 15 MB once. Learn tuios uses the same download.

An empty theme turns theming off. TUIOS then emits plain colour indices and your terminal's own palette decides what they look like.

Checking a theme

tuios list-themes <id> prints a theme's colours with the contrast each one measures against the theme's background. It tells you whether a palette is readable before you look at it.

tuios list-themes catppuccin_latte
tuios list-themes catppuccin_latte --json | jq -r '.palette.illegible[]'
tuios list-themes --json | jq -r .active

CharmTone themes Added in v0.10.0

Two built-in themes use CharmTone, the colour system of Charm.

ThemeGroundTextAccent
charmtonePepper #201F26Sash #ECEBF0Charple #6B50FF
charmtone-lightSalt #F7F6FBChar #3A3943Charple #6B50FF
[appearance]
theme = "charmtone"
background = "theme"   # paint the Pepper ground behind the panes

The dark theme uses the ANSI colours of Crush, the coding agent from Charm. Bright black is Squid, so that shell suggestions and comments are easy to read. The light theme uses a darker shade of each colour. CharmTone has no dark yellow, so yellow is Cumin, a light brown. Run tuios list-themes charmtone-light to see the contrast of each colour.

Gilt Added in v0.11.1

gilt is a dark theme of obsidian, parchment and gold. The gold is the yellow and also the accent of the interface.

[appearance]
theme = "gilt"

Importing a theme

tuios import-theme converts a kitty, ghostty, alacritty or wezterm colour scheme into a TUIOS theme. The format is read from the file's content, so the extension does not matter.

tuios import-theme ~/.config/kitty/current-theme.conf --name mine
tuios set-config appearance.theme mine

A scheme that sets only some colours imports those, and the rest fall back to the xterm defaults. Wezterm's TOML schemes are read. Its Lua schemes are not.

Writing a theme

A theme is a JSON file in ~/.config/tuios/themes/ (following $XDG_CONFIG_HOME). The file name without .json, lowercased, is its id unless the file sets id.

{
  "id": "my-theme",
  "display_name": "My Theme",
  "fg": "#e0def4",
  "bg": "#191724",
  "cursor": "#e0def4",
  "black": "#26233a",
  "red": "#eb6f92",
  "green": "#31748f",
  "yellow": "#f6c177",
  "blue": "#9ccfd8",
  "purple": "#c4a7e7",
  "cyan": "#ebbcba",
  "white": "#e0def4",
  "bright_black": "#6e6a86",
  "bright_red": "#eb6f92",
  "bright_green": "#31748f",
  "bright_yellow": "#f6c177",
  "bright_blue": "#9ccfd8",
  "bright_purple": "#c4a7e7",
  "bright_cyan": "#ebbcba",
  "bright_white": "#e0def4"
}
  • The colour names are purple and bright_purple, not magenta.
  • A colour is a hex string or an object: {"r": 255, "g": 0, "b": 0, "a": 255}.
  • Every field is optional. fg defaults to #e5e5e5, bg to #000000, cursor to fg, the eight normal colours to the xterm defaults, and each bright_* to its normal colour. Set the bright colours yourself, or bright text looks the same as normal text.
  • The directory is read again when you select a theme or run list-themes, so a file you just wrote can be selected at once. Subdirectories are not read.
  • A file that does not parse is skipped. tuios list-themes reports it under problems with the reason.

Chrome colours

The 16 ANSI colours are what programs in your panes paint with. By default TUIOS also takes its own accents from them: the logo and the selected row from bright_blue, the terminal-mode border from bright_green, and so on. A chrome object sets those accents directly, without changing what programs see:

{
  "id": "amber",
  "chrome": {
    "accent": "#ffb454",
    "accent_bright": "#ffd580",
    "success": "#aad94c",
    "warning": "#ffb454",
    "error": "#ff3333",
    "info": "#59c2ff",
    "surface": "#2b2118"
  }
}
FieldWhat it coloursTaken from when absent
accentLogo, selected row, window-mode pillbright_blue
accent_brightSecondary accent, focused border in window modebright_cyan
successTerminal-mode pill, focused border in terminal mode, success messagesbright_green
warningCopy-mode pill, warningsyellow
errorError messagesred
infoInfo messagesblue
surfaceThe fill of every dialog: palette, pickers, menus, which-keyA fixed dark grey, or on a light theme a step below its background
canvas, panel, cardThe darker and lighter steps around surfaceDerived from surface

Dialogs sit on a fixed grey ramp so they stay readable over any pane content. On a light theme the ramp is built from the theme's background instead, so a dialog is a light panel rather than a dark slab, and the screen behind it fades toward the background rather than toward black. The accent and key colours are darkened at their own hue until they read as text on it (4.5:1), and the status colours until they read as marks (3:1).

surface moves the ramp, and TUIOS picks text colours for it by contrast, so a light surface gets dark text. Text colours cannot be set directly. A field that is not a valid hex colour is ignored on its own.

Border colours

appearance.border_focused_color and appearance.border_unfocused_color override the theme's border colours. They live in config.toml, not in the theme. Clear one to hand the border back to the theme.

The focused border shows the mode: accent_bright in window mode and success in terminal mode. Two keys Added in v0.11.0 set the colour of one mode each:

[appearance]
border_focused_color_window = "accent"
border_focused_color_terminal = "#fab387"

A key for one mode wins over border_focused_color in that mode. A value is a hex colour, a palette index, a slot name such as blue, or a role name such as accent. The settings page has a row for each key, in the Appearance section. Each row opens a colour picker.

When you set no colour, the terminal-mode border is a step darker than the window-mode border on most themes. On many themes the cyan and the green have the same lightness. The step lets you see the mode without the hue. When darker is too faint, the step goes lighter. To keep one colour for both modes, set border_focused_color. At 16 colours the two modes keep bright cyan and bright green.

The default unfocused border is darker than the focused borders on a dark background, and lighter on a light one. You can see focus without the hue. With no theme, the unfocused border is a neutral grey near your terminal's background. At 16 colours it is bright black. A theme that names its unfocused border keeps that colour.

Two tiled panes in window mode. The focused pane has a blue border, from border_focused_color_window set to accent.
Window mode, with border_focused_color_window set to accent.
The same two panes in terminal mode. The focused border is peach, from border_focused_color_terminal.
The same pane in terminal mode, with border_focused_color_terminal set.

Colour depth

The chrome is designed for each colour depth a terminal can have, rather than drawn in truecolor and stepped down. TUIOS reads the depth the way other programs do, from TERM, COLORTERM and NO_COLOR. There is no setting for it.

DepthDetected whenWhat the chrome does
truecolorCOLORTERM=truecolor or 24bit, or a terminal known to have it (kitty, Ghostty, WezTerm, Alacritty, foot)The ramp described above
256TERM ends in 256color and COLORTERM is unset: Apple Terminal, mosh, tmux without TcThe greys sit on the xterm grey ramp (232 to 255), so no panel or selected row turns navy. Colours step to the nearest palette entry in OKLab, and a saturated colour never lands on a grey
16TERM=xterm, TERM=linux, or NO_COLOR setNo grounds are painted. Panels use your terminal's background and frame themselves with a line, the selected row and title chips are reverse video, and colours are your palette's slots

At 16 colours a theme's own colours give way to your terminal's palette slots, so set the terminal to the same theme to see them. The review diff is drawn per depth too: tinted lines in truecolor, fixed palette entries at 256 colours, and coloured line numbers with bold, underlined changed words at 16.

mosh passes 24-bit colour but not COLORTERM, so over mosh TUIOS sees 256 colours. If your terminal has truecolor, export COLORTERM=truecolor on the far machine.

Your terminal's colours

With no theme and no pane background, TUIOS asks each client's terminal for its background, foreground and 16 colours, and answers a program in a pane that asks for them (OSC 10, 11 and 4) with those. The chrome is measured against your terminal's background, so a light terminal gets the light ramp. A local client follows your system's light and dark switch as it happens. A client over SSH or in a browser asks once, when it attaches. A terminal that answers nothing, such as mosh, gets plain black and white; set a theme or appearance.pane_background there.

Added in v0.10.0 With a theme, a program in a pane gets the theme's background, text colour and 16 colours when it asks with OSC 10, 11 and 4. This is true for a pane in a daemon session too.

Light and dark reports Added in v0.10.0

A program that turns on mode 2031 gets a report when the background of its pane changes between dark and light: CSI ? 997 ; 1 n for dark and CSI ? 997 ; 2 n for light. The report comes when your terminal changes its colour scheme, and when the theme changes, such as an Omarchy theme switch. TUIOS sends no SIGWINCH.

Neovim: follow your look

Neovim gets 'background' right from these reports, but your colorscheme keeps its own palette. The community plugin tuios-look-sync.nvim builds a base16 colorscheme from the theme that TUIOS shows. When you apply a look from the gallery with tuios look apply, Neovim repaints to match. tuios look remove puts your fallback colorscheme back.

It needs Neovim 0.10 or later and mini.base16. With lazy.nvim:

{
  "nkapila6/tuios-look-sync.nvim",
  lazy = false,
  priority = 1000,
  dependencies = { "nvim-mini/mini.base16" },
  opts = { fallback = "tokyonight" },
  config = function(_, opts)
    require("tuios-look-sync").setup(opts)
    vim.cmd.colorscheme("tuios")
  end,
}

Limits

  • The plugin reads theme files. A built-in theme such as dracula is not a file, so Neovim uses the fallback colorscheme.
  • Neovim must run on the machine that has the TUIOS config. Over SSH from a pane, you get the fallback colorscheme.

nkapila6 wrote and maintains tuios-look-sync.nvim. Report problems with the plugin in its repository.

See also: the Neovim page.

Cursor colour Added in v0.9.3

A program in a pane can set the cursor colour with OSC 12. TUIOS sends the colour of the focused pane to your terminal. When the program resets the colour with OSC 112, your terminal's own cursor colour comes back. It also comes back when the focus moves to a pane that set no colour. This works in a native terminal and in tuios-web.

Glyph sets

A glyph set picks the shapes the chrome is drawn with. Four ship: default, unicode (no Nerd Font glyphs), heavy and ascii.

tuios set-config appearance.glyphs heavy
tuios set-config appearance.border_style glyphs
tuios list-glyphs heavy

With no set configured and no --ascii-only, TUIOS picks one from the environment: a locale that is not UTF-8 (C, POSIX, ISO-8859-1, read from the first of LC_ALL, LC_CTYPE and LANG that is set) gets ASCII, and the Linux console (TERM=linux) gets unicode. tuios list-glyphs with no argument says which set that is and why.

border_style = "glyphs" is what makes the border follow the set. The settings page has a searchable Glyph set picker with a live preview. Writing your own set, the roles it can name and the width rules are covered in Configuration.

Spacing and text

tuios set-config appearance.gap 2                 # cells between tiled panes, 0 to 8
tuios set-config appearance.panel_padding 4       # columns inside dialogs, 1 to 6
tuios set-config appearance.clock_format "Mon 3:04PM"
tuios set-config appearance.window_title_format "{index}: {title}"
  • window_title_format accepts {title}, {index} and {cwd}.
  • dock_workspace_tab_format accepts {index} and {name}.
  • clock_format is a Go time layout, such as 15:04 or Mon 3:04PM.

Quieting what you are not using

KeyDefaultMeaning
appearance.dim_unfocused0Fade panes you are not in, as a percent from 0 to 90. 0 is off
appearance.zen_mode"disabled"Hide pane borders: disabled, always, or mouse (hidden while the mouse is still)
appearance.border_style"rounded"rounded, normal, thick, double, block, outer-half-block, inner-half-block, ascii, hidden or glyphs

dim_unfocused dims pane content only. Borders, title bars, the rail and the dock stay as they are.

With theme = "none", TUIOS dims with the colours that your terminal reports. Text in the default colour moves toward your terminal's background, and the 16 ANSI colours come from your terminal's palette. A cell with no background keeps none, so a translucent terminal shows no opaque block. If your terminal reports no colours, the text is drawn faint. appearance.dim_foreground = false keeps the text at full strength and dims only the background.

Selection and search colours

[appearance.selection] holds the colours a pane marks text with. They are settings rather than part of the theme, because TUIOS chooses them and the program in the pane does not.

KeyDefaultMeaning
bg / fg#45475A / emptySelected text. An empty fg keeps the text's own colour
boldfalseAlso draw selected text bold
search_bg / search_fg#8A6D2F / #F5E7C8Every search match
match_bg / match_fg#E5A93D / #1C1B19The match under the cursor
cursor_bg / cursor_fg#39C5CF / #08222BThe copy mode cursor
flashtrueSweep a band of light over text you just copied. The sweep follows appearance.motion: basic and full draw it, none turns it off
flash_ms420How long the sweep takes, 80 to 3000
flash_style"diagonal"diagonal, diagonal-reverse, horizontal or vertical
flash_coloremptyThe colour of the sweep

The scrollback browser uses the same search and selection colours.

Spotlight

The spotlight lights one area of the screen and dims the rest. It is meant for recordings and demos. Press B in window management mode, Ctrl+B B in any mode, or run Toggle spotlight from the palette. The key was b in earlier versions.

While the spotlight is on, the dock shows a Spotlight chip. Click it to turn the spotlight off. Esc in window mode also turns it off. In terminal mode, Esc goes to the program in the pane, so use Ctrl+B B. See Spotlight.

KeyDefaultMeaning
spotlight.enabledfalseStart with the spotlight on
spotlight.follow"mouse"Follow the mouse or the focused pane's cursor
spotlight.radius10Half the beam's height, in rows
spotlight.dim75Percent of its light an unlit cell loses
spotlight.edge"hard"hard cuts the beam off, soft fades it
spotlight.shakefalseShake the mouse left and right to toggle the beam

The spotlight belongs to one client. Another client attached to the same session sees its own screen unchanged. Over SSH or in the browser, follow = "cursor" and edge = "hard" send far fewer bytes.

tuios lives only at tuios.dev and github.com/Gaurav-Gosain/tuios. tuios has no X or Twitter account. An account that offers a tuios token or presale is not this project.

On this page