| 📦 Turbo Python 6fc62ea k33g 11h ago | 1 | # Reference: theme file format |
| 2 | |
| 3 | > Neutral, exhaustive description of a Turbo Python theme file. |
| 4 | |
| 5 | A theme is a TOML file. Themes are read from the user theme directory first, then from the ones embedded in the binary; a user file wins over an embedded theme of the same name. |
| 6 | |
| 7 | ## Locations |
| 8 | |
| 9 | | Location | Notes | |
| 10 | | --- | --- | |
| 11 | | `$TURBO_PYTHON_THEME_DIR` | Used when the variable is set and non-empty. | |
| 12 | | `~/.config/turbo-python/themes` | Linux (`os.UserConfigDir`). | |
| 13 | | `~/Library/Application Support/turbo-python/themes` | macOS. | |
| 14 | | embedded | `turbo-classic`, `turbo-dark`, `borland-light`, `cappuccino`, `catppuccin-frappe`, `catppuccin-latte`, `cobalt`, `darcula`, `intellij-light`, `monochrome-dark`, `monochrome-light`. | |
| 15 | |
| 16 | A theme's **name** for `-theme` and for `Options ▸ Theme…` is its file name without `.toml`. It may not contain `/`, `\` or `..`. |
| 17 | |
| 18 | ## The themes that ship |
| 19 | |
| 20 | | Name | Ground | For | |
| 21 | | --- | --- | --- | |
| 22 | | `turbo-classic` | Borland navy | The default: the palette Turbo C had | |
| 23 | | `turbo-dark` | Neutral dark grey | Modern terminals with true colour | |
| 24 | | `borland-light` | Paper white | Bright rooms and projectors | |
| 25 | | `cappuccino` | Espresso brown | The Turbo layout with the temperature up: milk in the text, caramel where Turbo Dark puts blue | |
| 26 | | `catppuccin-frappe` | Warm slate | The Catppuccin Frappé palette, unchanged: pastel accents on a soft dark ground | |
| 27 | | `catppuccin-latte` | Warm paper | The Catppuccin Latte palette, unchanged: the same mapping with the saturation a light ground needs | |
| 28 | | `cobalt` | Deep navy | The Cobalt palette, accents kept as loud as they are known for | |
| 29 | | `darcula` | Charcoal | After JetBrains' Darcula: orange keywords, green strings, and the orange punctuation that makes it recognisable | |
| 30 | | `intellij-light` | White | After JetBrains' IntelliJ Light: blue bold keywords, green bold strings | |
| 31 | | `monochrome-dark` | Black and greys | No hue at all — code told apart by lightness, bold, italic and underline | |
| 32 | | `monochrome-light` | Paper and greys | The same, the other way up: on paper the darkest grey is the loudest | |
| 33 | |
| 34 | Every one of them **states its whole palette** rather than inheriting most of it. A theme you write yourself may inherit; see [writing one](../how-to/write-a-theme.md). |
| 35 | |
| 36 | ## A name a theme used to answer to |
| 37 | |
| 38 | `monochrome` still loads. It is what this theme shipped as before `monochrome-light` joined it and the pair was renamed, and a settings file or a `-theme` flag saying `monochrome` gets `monochrome-dark`. |
| 39 | |
| 40 | | Retired name | Loads | |
| 41 | | --- | --- | |
| 42 | | `monochrome` | `monochrome-dark` | |
| 43 | |
| 44 | A retired name is **not** listed by `-theme` or by **Options ▸ Theme…**, so each theme appears once, under the name it has now. A theme of your own called `monochrome.toml` still wins over it, exactly as it would for any other name. |
| 45 | |
| 46 | ## Top-level fields |
| 47 | |
| 48 | | Field | Type | Default | Description | |
| 49 | | --- | --- | --- | --- | |
| 50 | | `name` | string | the file's base name | Display name, shown in the theme picker and the About box. | |
| 51 | | `description` | string | `""` | One line, shown by `-list-themes`. | |
| 52 | | `inherits` | string | none | Name of a theme to start from. Its resolved styles are the base; this file overrides what it names. Chains are capped at 16 hops. | |
| 53 | | `colors` | table | `{}` | The styles. Keys are the style keys below. | |
| 54 | |
| 55 | ## Entry fields |
| 56 | |
| 57 | Each value under `[colors]` is an inline table: |
| 58 | |
| 59 | | Field | Type | Default | Description | |
| 60 | | --- | --- | --- | --- | |
| 61 | | `fg` | string | inherited | Foreground colour. | |
| 62 | | `bg` | string | inherited | Background colour. | |
| 63 | | `bold` | bool | `false` | Switch bold on. | |
| 64 | | `underline` | bool | `false` | Switch underline on. | |
| 65 | | `italic` | bool | `false` | Switch italic on. | |
| 66 | | `reverse` | bool | `false` | Swap foreground and background. | |
| 67 | | `dim` | bool | `false` | Switch dim on. | |
| 68 | | `blink` | bool | `false` | Switch blink on. | |
| 69 | |
| 70 | Attributes are only ever switched **on**; there is no way to switch an inherited attribute off other than by not inheriting it. |
| 71 | |
| 72 | ## Colour values |
| 73 | |
| 74 | | Form | Example | Notes | |
| 75 | | --- | --- | --- | |
| 76 | | ANSI name | `navy`, `aqua`, `silver`, `fuchsia` | The sixteen names, plus the full W3C list. | |
| 77 | | Hex literal | `#5fafd7` | 24-bit; tcell approximates it on terminals without true colour. | |
| 78 | | `default` | `default` | Whatever the terminal itself uses. | |
| 79 | | `-` | `-` | Same as `default`. | |
| 80 | | `""` | `""` | Same as `default`. | |
| 81 | |
| 82 | The sixteen ANSI names: `black` `maroon` `green` `olive` `navy` `purple` `teal` `silver` `gray` `red` `lime` `yellow` `blue` `fuchsia` `aqua` `white`. |
| 83 | |
| 84 | An unrecognised colour is a **load error**, not a silent fallback. |
| 85 | |
| 86 | ## Style keys |
| 87 | |
| 88 | Undefined keys fall back along the dots, and finally to `default`. |
| 89 | |
| 90 | ### Base |
| 91 | |
| 92 | | Key | What it colours | |
| 93 | | --- | --- | |
| 94 | | `default` | The last resort of every lookup | |
| 95 | | `desktop` | The patterned backdrop behind the windows | |
| 96 | | `shadow` | The cells a window darkens behind itself | |
| 97 | |
| 98 | ### Menu bar |
| 99 | |
| 100 | | Key | What it colours | |
| 101 | | --- | --- | |
| 102 | | `menu.bar` | The row of titles | |
| 103 | | `menu.item` | A drop-down entry | |
| 104 | | `menu.selected` | The highlighted entry | |
| 105 | | `menu.shortcut` | The hot letter of a label | |
| 106 | | `menu.disabled` | An entry that cannot be chosen | |
| 107 | |
| 108 | ### Windows |
| 109 | |
| 110 | | Key | What it colours | |
| 111 | | --- | --- | |
| 112 | | `window.frame.active` | The frame of the focused window | |
| 113 | | `window.frame.inactive` | Every other frame | |
| 114 | | `window.title.active` | The focused window's title | |
| 115 | | `window.title.inactive` | Every other title | |
| 116 | | `window.body` | The interior, before its content draws | |
| 117 | |
| 118 | ### Bars |
| 119 | |
| 120 | | Key | What it colours | |
| 121 | | --- | --- | |
| 122 | | `statusbar` | The bar itself | |
| 123 | | `statusbar.key` | The `Fn` part of a hint | |
| 124 | | `statusbar.hint` | The right-aligned text | |
| 125 | | `scrollbar` | A scroll bar's track | |
| 126 | | `scrollbar.thumb` | Its thumb and arrows | |
| 127 | |
| 128 | ### Dialogs and controls |
| 129 | |
| 130 | | Key | What it colours | |
| 131 | | --- | --- | |
| 132 | | `dialog.frame` | A dialog's frame | |
| 133 | | `dialog.body` | Its interior | |
| 134 | | `dialog.title` | Its title | |
| 135 | | `dialog.label` | A line of static text | |
| 136 | | `button` | A button | |
| 137 | | `button.focused` | The focused button | |
| 138 | | `button.shortcut` | The hot letter of a button | |
| 139 | | `input` | An input field | |
| 140 | | `input.focused` | The focused input field | |
| 141 | | `input.selection` | Selected text in an input field | |
| 142 | | `list` | A list box | |
| 143 | | `list.selected` | Its highlighted line, when focused | |
| 144 | | `list.unfocused` | Its highlighted line, when not | |
| 145 | | `checkbox` | A check box | |
| 146 | | `checkbox.focused` | The focused check box | |
| 147 | |
| 148 | ### Editor |
| 149 | |
| 150 | | Key | What it colours | |
| 151 | | --- | --- | |
| 152 | | `editor.text` | Text no other rule claims | |
| 153 | | `editor.selection` | Selected text | |
| 154 | | `editor.linenumber` | The line-number gutter | |
| 155 | | `editor.currentline` | The line the cursor is on | |
| 156 | | `editor.cursor` | The cursor. Its **background** is also sent to the terminal as its cursor colour, and its foreground paints the character underneath. | |
| 157 | |
| 158 | ### Terminal |
| 159 | |
| 160 | | Key | What it colours | |
| 161 | | --- | --- | |
| 162 | | `terminal.text` | Every cell of a terminal window whose colour the program running in it did not choose | |
| 163 | | `terminal.cursor` | The cell under a terminal's cursor, when that window has the focus | |
| 164 | |
| 165 | A program that names its own colours keeps them: these two only fill in what it left unset. See [Terminal windows](terminal.md). |
| 166 | |
| 167 | ### Project tree |
| 168 | |
| 169 | | Key | What it colours | |
| 170 | | --- | --- | |
| 171 | | `tree.text` | A file's name in the project tree, and the tree's background | |
| 172 | | `tree.directory` | A directory's name | |
| 173 | | `tree.selected` | The highlighted row, when the tree has the focus | |
| 174 | | `tree.unfocused` | The highlighted row, when it does not | |
| 175 | |
| 176 | These are separate from the `list.*` keys on purpose: a dialog's list is coloured against a dialog, and reusing it would highlight a tree row in the very colour a window's body already is. See [Project tree](project-tree.md). |
| 177 | |
| 178 | ### Syntax |
| 179 | |
| 180 | | Key | What it colours | |
| 181 | | --- | --- | |
| 182 | | `syntax.identifier` | An ordinary name | |
| 183 | | `syntax.keyword` | `func`, `if`, `package`, … | |
| 184 | | `syntax.type` | `int`, `string`, and a name after `type` | |
| 185 | | `syntax.builtin` | `len`, `append`, `make`, … | |
| 186 | | `syntax.constant` | `true`, `false`, `nil`, `iota` | |
| 187 | | `syntax.function` | A name before `(`, or after `func` | |
| 188 | | `syntax.string` | A string literal | |
| 189 | | `syntax.char` | A rune literal | |
| 190 | | `syntax.number` | An integer, float or imaginary literal | |
| 191 | | `syntax.comment` | `//` and `/* */` | |
| 192 | | `syntax.operator` | `+`, `:=`, `<-`, … | |
| 193 | | `syntax.punctuation` | Brackets, commas, dots, semicolons | |
| 194 | | `syntax.heading` | A Markdown heading, whole line | |
| 195 | | `syntax.tag` | An HTML element name and its brackets | |
| 196 | | `syntax.attribute` | An HTML attribute's name | |
| 197 | | `syntax.emphasis` | Markdown bold and italic | |
| 198 | | `syntax.link` | A Markdown link or image | |
| 199 | |
| 200 | Which language produces which class is in [Languages coloured](languages.md). |
| 201 | |
| 202 | ### Completion and diagnostics |
| 203 | |
| 204 | | Key | What it colours | |
| 205 | | --- | --- | |
| 206 | | `completion.frame` | The popup's frame | |
| 207 | | `completion.item` | A suggestion | |
| 208 | | `completion.selected` | The highlighted suggestion | |
| 209 | | `completion.detail` | The kind tag beside a suggestion | |
| 210 | | `diagnostic.error` | An error from the language server | |
| 211 | | `diagnostic.warning` | A warning | |
| 212 | | `diagnostic.info` | A note | |
| 213 | |
| 214 | ## Example |
| 215 | |
| 216 | ```toml |
| 217 | name = "Mine" |
| 218 | description = "Turbo Classic, with readable comments." |
| 219 | inherits = "turbo-classic" |
| 220 | |
| 221 | [colors] |
| 222 | "syntax.comment" = { fg = "#8a8a8a", italic = true } |
| 223 | "syntax.string" = { fg = "#87d7af" } |
| 224 | "editor.currentline" = { bg = "#00005f" } |
| 225 | ``` |
| 226 | |
| 227 | ## Errors |
| 228 | |
| 229 | | Message | Cause | |
| 230 | | --- | --- | |
| 231 | | `theme: not found: "x"` | No `x.toml` in the user directory or among the embedded themes. | |
| 232 | | `theme: not found: "…" is not a plain theme name` | The name contains `/`, `\` or `..`. | |
| 233 | | `invalid TOML: …` | The file is not valid TOML. | |
| 234 | | `colors."k": fg: unknown colour "…"` | The colour name is not recognised. | |
| 235 | | `inherits: chain deeper than 16, probably a loop` | Two themes inherit from each other, directly or through others. | |
| 236 | | `inherits "x": theme: not found` | The parent named does not exist. | |