turbo-editors/turbo-gopublic Fork 0
145937ab1c0750b59c3b2770fac6c2875b5eec4d
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-go.git
git clone ssh://git@rickub.com/turbo-editors/turbo-go.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

write-a-theme.md · 152 lines · 7.9 KBmarkdown Blame HistoryRaw
📦 Turbo Go 3d7798b k33g 13h ago1# How to write your own theme
2
3This guide shows how to add a colour theme of your own. It assumes you know where your configuration directory is and can edit a TOML file.
4
5## 1. Find where themes go
6
7```bash
8turbo-go -list-themes
9```
10
11The last line tells you the directory — `~/.config/turbo-go/themes` on Linux, `~/Library/Application Support/turbo-go/themes` on macOS. Create it:
12
13```bash
14mkdir -p ~/.config/turbo-go/themes
15```
16
17## 2. Start from an existing theme
18
19The quickest start is to inherit from one that already works and override only what you want:
20
21```toml
22# ~/.config/turbo-go/themes/mine.toml
23name = "Mine"
24description = "Turbo Classic, but the comments are readable."
25inherits = "turbo-classic"
26
27[colors]
28"syntax.comment" = { fg = "#8a8a8a", italic = true }
29"syntax.string" = { fg = "#87d7af" }
30```
31
32Everything you do not set is taken from `turbo-classic`.
33
34**Inherit from a theme whose ground is the same as yours.** The colours you leave out were chosen against the background of the theme you inherit from, so a dark theme built on `turbo-classic` will show, here and there, a colour picked for Borland navy. If you are writing a dark theme, inherit from `turbo-dark`, `cappuccino`, `catppuccin-frappe`, `cobalt`, `darcula` or `monochrome-dark`; if a light one, from `borland-light`, `catppuccin-latte`, `intellij-light` or `monochrome-light`. That is also why the eleven themes that ship in the binary each state their palette in full rather than inheriting most of it — a test holds them to it, because a shipped theme is one the project is answerable for.
35
36## 3. Use it
37
38```bash
39turbo-go -theme mine main.go
40```
41
42Or from inside the editor: `Options ▸ Theme…`, which lists every theme it can find.
43
44## 4. Iterate
45
46Edit the file, then restart the editor. There is no live reload.
47
48If the theme fails to load, Turbo Go falls back to the default rather than refusing to start. To see *why* it failed:
49
50```bash
51turbo-go -list-themes
52```
53
54A broken theme is listed with the parse error beside it — an unknown colour name is an error, not a silent fallback, so a typo is pointed at rather than quietly repainting half the screen.
55
56## 5. Check it stays readable
57
58The project holds every theme it ships to five measured rules, and they are worth applying to your own. `make test` runs them.
59
60| Rule | Why |
61| --- | --- |
62| The cursor is at least 64 apart from the line it sits on, in its strongest channel | A terminal draws its cursor over the cell; one that blends in cannot be found |
63| The cursor is never a plain reversal of that line | A terminal that draws its cursor by inverting the cell would invert it back into invisibility |
64| The current line is at least 16 from the page | `turbo-dark` once used ten, which is no highlight at all |
65| Text you have to read is at least 64 from its background | Furniture — the desktop, a shadow, a scrollbar trough, a disabled entry — is exempt: it exists to recede |
66| Comments read at 4.5:1 or better against their background, by WCAG relative luminance | A comment is prose, read word by word. `turbo-classic` drew them in `#808080` on its navy: 128 channel values apart, so the rule above waved it through, and 4.05:1 to read, which is below the W3C's floor for body text. Comments were the dimmest colour in six of the eight shipped themes. |
67
68
69The contrast rule is applied to the six themes this project authors. The two Catppuccin themes are exempt, and the exemption is written where it is made: their colours are somebody else's published palette, faithfully copied, and Catppuccin puts comments at 2.87:1 in Frappé and 2.83:1 in Latte. A theme called Catppuccin that is not those exact values is a different theme wearing a borrowed name, so the fix — if anyone wants one — is upstream.
70
71It is applied to comments and to nothing else. `syntax.punctuation` is quieter still in several themes and stays that way: punctuation is recognised by shape, not read.
72
73A sixth rule catches the mistake no measurement finds: **two syntax classes a reader meets side by side must not be drawn identically**. `turbo-classic` once painted `syntax.link` the same lime as `syntax.string`, so a Markdown link and an inline code span were the same thing on screen — every colour readable, every key set, and the two simply equal. Both monochromes pass this rule with no hue at all, by using bold, italic and underline instead.
74
75## Variants
76
77**Override a shipped theme rather than adding one.** Name your file after it — `turbo-classic.toml` — and yours wins. The embedded one is not replaced, so deleting your file brings it back.
78
79**Start from scratch.** Leave `inherits` out. Set at least `default`; every key you do not set falls back along the dots to it, so a theme with one line is still a usable theme.
80
81**Colour only the syntax.** One key does it:
82
83```toml
84[colors]
85syntax = { fg = "silver" }
86```
87
88`syntax.keyword`, `syntax.string` and the rest all fall back to it.
89
90**Keep the terminal's own colours.** Use `default` as a colour value:
91
92```toml
93[colors]
94"editor.text" = { fg = "default", bg = "default" }
95```
96
97**Test it in a checkout without installing it.** Point the editor at any directory:
98
99```bash
100TURBO_GO_THEME_DIR=./my-themes turbo-go -theme mine main.go
101```
102
103**The cursor is hard to see.** `editor.cursor` does two things: its **background** is sent to the terminal as the cursor's own colour, and it also paints the cell underneath as a fallback for terminals that ignore that. Set it to something loud:
104
105```toml
106[colors]
107"editor.cursor" = { fg = "#000000", bg = "#ff8700" }
108```
109
110Two things make a cursor colour a bad one, and the test suite rejects both: a plain reversal of the line — which terminals that draw their cursor by inverting the cell turn back into invisibility — and anything less than 64 channel values away from the line it sits on.
111
112**The cursor's line is hard to find.** That is `editor.currentline`, and it is a different key. It has to differ from `editor.text` by at least 16 channel values to count as a highlight at all.
113
114**Markdown and HTML look plain.** Five keys belong to the markup languages and have no equivalent in Go, so a theme written before they existed does not set them:
115
116```toml
117[colors]
118"syntax.heading" = { fg = "white", bold = true }
119"syntax.tag" = { fg = "aqua" }
120"syntax.attribute" = { fg = "yellow" }
121"syntax.emphasis" = { fg = "fuchsia", bold = true }
122"syntax.link" = { fg = "aqua", underline = true }
123```
124
125Give `syntax.link` a different colour from `syntax.string`: a link and an inline `code` span sit side by side in most prose, and sharing a colour makes them one blur. The shipped `turbo-classic` had exactly that fault until it was looked at on a real terminal.
126
127**The project tree looks flat.** It has four keys of its own, and none of them falls back to `list`:
128
129```toml
130[colors]
131"tree.text" = { fg = "silver", bg = "navy" }
132"tree.directory" = { fg = "white", bg = "navy", bold = true }
133"tree.selected" = { fg = "black", bg = "aqua" }
134"tree.unfocused" = { fg = "black", bg = "gray" }
135```
136
137Give `tree.text` the same background as `window.body`, so the tree looks like part of its window, and make `tree.selected` clearly different from it — the test suite holds every shipped theme to at least 64 channel values between the two, because a highlight the same colour as the page is no highlight.
138
139**Terminal windows look wrong.** They have two keys of their own, and neither falls back to `editor`:
140
141```toml
142[colors]
143"terminal.text" = { fg = "silver", bg = "black" }
144"terminal.cursor" = { fg = "black", bg = "aqua" }
145```
146
147`terminal.text` is what a shell's output gets when it names no colour of its own — set it to something close to a real terminal rather than to your editor background, or `less` and `htop` will look out of place. A program that does name its colours keeps them either way.
148
149## See also
150
151- Every key you may set, and every colour name: [theme file reference](../reference/themes.md)
152- Why the format is TOML with two kinds of inheritance: [Design decisions](../explanation/design-decisions.md)