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)
| Name | Tone |
|---|---|
catppuccin-mocha | dark (default) |
catppuccin-macchiato | dark |
catppuccin-latte | light |
Cross-editor families (each -dark / -light)
| Family | Dark | Light |
|---|---|---|
| Gruvbox | gruvbox-dark | gruvbox-light |
| Tokyo Night | tokyonight-dark | tokyonight-light |
| Dracula | dracula-dark | dracula-light |
| Nord | nord-dark | nord-light |
| Solarized | solarized-dark | solarized-light |
| One | one-dark | one-light |
| Everforest | everforest-dark | everforest-light |
| Rosé Pine | rosepine-dark | rosepine-light |
| Monokai | monokai-dark | monokai-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
:customizewith 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 withset 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.
Related options
ui.nerd_fonts— toggles the icon palette used by the file tree, oil, pickers, and gutter.onuses 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. Pickoffif 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.