# tui/set-font Apply a monospaced font live — the workspace grid, popped panel windows, and surface text all re-render at the chosen face and size on the next host frame. ## Syntax
[tui/set-font "JetBrains Mono"]                  # family name
[tui/set-font "JetBrains Mono" 16]               # family + size
[tui/set-font "/usr/share/fonts/x/x.ttf"]        # exact file path
[tui/set-font %{:family "JetBrains Mono" :cut :bold :size 16}]
[tui/set-font %{:path "/home/u/.fonts/x.ttf" :size 16}]
[tui/set-font %{:size 20}]                       # size-only — keeps the font
## Parameters - `spec` — a string or a map: - string — an existing font file path (absolute or relative to the working directory) is used verbatim; anything else is treated as a family name and resolved by scanning the font directories. - map — `:family` with an optional `:cut` (portable; tried first), and/or `:path` (exact file; fallback when the family is absent or doesn't resolve) and/or `:size`. A `:size`-only map keeps the current font. - `cut` — how `:family` picks the style face: `:regular` (default), `:bold`, `:italic`, or `:bold-italic` (`:oblique` aliases italic; case/space/hyphen-insensitive). - `size` (optional second positional arg) — pixel size; a missing size keeps the current one. ## Resolution Family names scan the directories the system's fontconfig configuration declares (the `<dir>` entries in `$FONTCONFIG_FILE` when set, else `~/.config/fontconfig/fonts.conf` and `/etc/fonts/fonts.conf` plus its `conf.d/*.conf` snippets — this is how X11 subdirs, Flatpak exports and Nix store fonts are found) along with `$XDG_DATA_DIRS` entries; user dirs (`$XDG_DATA_HOME/fonts` else `~/.local/share/fonts`, `~/.fonts`) are searched first, and `/usr/local/share/fonts`/`/usr/share/fonts` are the fixed fallbacks. The scan is recursive (`.ttf`/`.otf`/`.ttc`) and matches normalised file stems: the requested `:cut` wins, then "Regular" cuts, then shorter stems (a family without the requested cut falls back with a warning). Every candidate must be effectively monospaced — declared fixed-width, or with uniform glyph advances (Google's Noto Mono TTFs declare neither flag nor advance in the usual way; the probe catches them). Proportional fonts are rejected. `:size` clamps to 6–128. A failed resolution returns `false` and logs a diagnosis to stderr (`font: no font matching family "..."`, `font:` file is not fixed-width: ...`).` ## Returns `true` when the change was queued (the rebuild lands on the next host frame), `false` when the resolution failed or no workspace is attached. ## Notes - Applies live. The atlas + cell grid rebuild on the main thread — the grid re-layouts, popped panel windows re-atlas under their own GL contexts, and surface text follows. Nothing restarts. - GL hosts only. `tui/set-font` returns `false` on the ANSI host (`retra` renders through the terminal emulator's font) and on hosts with no workspace. - A successful apply moves the Ctrl+0 zoom-reset base to the chosen size (interactive zoom: Ctrl+= / Ctrl+- / Ctrl+0, browser-style). - Session-only — like the Ctrl+=/- zoom, an apply is not persisted. Set the project default with `:font` in the prelude (`.deft/prelude.dft`): `:font %{:family "JetBrains Mono" :cut :regular :size 16}`. `[tui/save]` records the applied face in the workspace spec as `:family` + `:cut`, so saved workspaces stay portable across distros (paths are only written for faces that report no family). - Applies the primary face and size. The prelude `:font :fallback` faces and `:ranges` pre-rasterization stay in effect across applies (they're prelude-configured) — see the prelude manual. Glyph coverage itself is dynamic: characters outside the startup set rasterize on demand, so switching fonts never loses scripts. ## Example — a font picker
# Combined with dialog/search (see tui/font-list):
set chosen [dialog/search "Font" [tui/font-list]]
if ($chosen != nil) { [tui/set-font $chosen 16] }
## See Also `tui/font`, `tui/font-list`, `tui/cell-size`