Themes & colorschemes

A theme is the editor's colour identity — syntax highlighting, gutter signs, the modeline, diff tints, popups, the canvas itself. In lattice a theme is a palette (a set of named colour roles like text, green, red, overlay) plus an element registry that maps every styled surface to a role. Swapping the palette recolours the whole editor at once; there is no per-surface theme wiring to maintain.

One model, two renderers. The TUI inherits the terminal's own background/foreground for the canvas (it can't repaint the terminal), so swapping to a light theme there recolours syntax and chrome but leaves the terminal's canvas. The GPUI renderer owns its canvas and recolours fully, light or dark.


Quick reference

You want…Do this
Switch to a known theme:colorscheme tokyonight-dark
Browse themes with live preview:colorscheme (no argument)
Vim short for the above:colo gruvbox-light
Tweak a config group in a buffer:customize ui
Pick a group/mode to customize:customize (no argument)
Toggle the icon palette:set ui.nerd_fonts / :set noui.nerd_fonts

Switching themes

:colorscheme <name> switches the active theme by name. The whole editor recolours immediately:

:colorscheme dracula-dark
:colo nord-light

:colo is the vim short. An unknown name echoes an error and leaves the current theme untouched — nothing changes until a real name lands. To browse instead of typing a name, run :colorscheme with no argument — the live-preview picker (next section).

The live-preview picker

:colorscheme with no argument opens a buffer-backed picker over every registered theme. As you move the selection, the whole editor recolours to that candidate — you see the real theme, not a swatch (the cross-editor convention: VSCode, Zed, and telescope all preview this way).

  • <CR> (accept) commits the highlighted theme.
  • <Esc> (cancel) restores the theme that was active when you opened the picker — byte-for-byte, no residue.

The picker is the way to shop for a theme; the explicit :colorscheme <name> form is the way to set one you already know.


The builtin catalog

Lattice ships 21 builtin themes. Catppuccin contributes three flavours; nine cross-editor families each ship a dark and a light variant.

Catppuccin (the default family)

NameTone
catppuccin-mochadark (default)
catppuccin-macchiatodark
catppuccin-lattelight

Cross-editor families (each -dark / -light)

FamilyDarkLight
Gruvboxgruvbox-darkgruvbox-light
Tokyo Nighttokyonight-darktokyonight-light
Draculadracula-darkdracula-light
Nordnord-darknord-light
Solarizedsolarized-darksolarized-light
Oneone-darkone-light
Everforesteverforest-darkeverforest-light
Rosé Pinerosepine-darkrosepine-light
Monokaimonokai-darkmonokai-light

The default on a fresh start is catppuccin-mocha. Markdown headings get distinct per-level colour and (on the GPUI renderer) per-level size — h1 down to h6 each pick up their own style, with the leading # markers left at base size.


Customizing options

Themes set colours; many other surfaces (icons, separators, gutter behaviour) are typed options. :customize opens a type-aware editing view that writes back to your TOML config:

:customize ui          # every customizable option in the `ui` group
:customize lsp-mode     # what a mode contributes
:customize             # a navigation picker: groups + modes
  • :customize with no argument lists every option group and every mode that contributes options — pick one to drill in.
  • :customize <group> or :customize <mode> opens the focused view: each option shows its name, type, current value, default, and doc.
  • Following an option's edit link prefills the : command line with set NAME=VALUE, where you finish the value and accept.

For the concepts behind options (:set, layered resolution, where a value comes from) see Options. :colorscheme itself is not persisted across restarts yet — set it from your init to make it stick.


Registering your own theme

The theme catalog is open. A custom palette registered into it gains everything the builtins have: :colorscheme <your-name>, completion, and a slot in the live-preview picker.

Registration is the register_theme seam, reached from your Rust-WASM init (and, later, from a plugin via WIT). You supply a name and a palette that fills the same role-key vocabulary the builtins reference (text, overlay, subtext, green, red, orange, purple, cyan, the base/surface canvas family, the ansi.* chrome, …). Because every styled element resolves through those roles, a palette alone recolours the whole editor — you don't wire individual elements. Registering does not change the active theme; it just adds it to the catalog, ready for :colorscheme.

Re-registering an existing name replaces that theme's palette, so you can override a builtin in place by registering under its name.


  • ui.nerd_fonts — toggles the icon palette used by the file tree, oil, pickers, and gutter. on uses Nerd Fonts v3 glyphs (requires a patched terminal/GUI font like JetBrains Mono Nerd Font); off (the default) falls back to a BMP-block palette (◆ ≡ ◇ ■ ♪ ▶ ·) that renders in any monospace font. Flip it with :set ui.nerd_fonts / :set noui.nerd_fonts. Pick off if you see ? boxes.

See also

  • Options:set, :customize, the typed-option model.
  • Modeline — the status row whose colours follow the active theme.
  • Display & layout — gutter, whitespace, soft-wrap.