1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// Themes: choosing one, the native palettes and the faithful ports, and
// the roles a theme file sets.
#import "style.typ": key, keys, btn, chord, word, tag, addr, file, cmd, doc, pairs
#word("Themes") (#key("SPC t t")) lists every theme as a word to click;
`Theme <name>` sets one anywhere, and the same line in the startup file
keeps it. #word("NextColor") walks the ring: the native themes first, then
`acme`, `lapis` and `lapis_plain`, the faithful ports, the legacy `helix`
and `dark`, and the palettes imported from helix and zed. `orchard` is the
default. `lapis` draws its ornament in the GUI; `lapis_plain` is the same
theme on flat grounds, keeping its framed and shadowed tags and its
file-name shadow.
= The native themes
#pairs(
[`orchard`], [near-black evergreen; bright leaf comments and plum syntax],
[`dusk`], [soft plum charcoal; copper comments and gentle text],
[`ink`], [pure black; bright, distinct signals and ice-blue comments],
[`paper`], [neutral uncoated paper; graphite and teal],
[`daybreak`], [high-contrast light; white and deep blue ink],
[`atelier`], [acme homage; butter-yellow paper and blue-green tags],
[`forge`], [Dark Plus-inspired near-black, blue and peach; slate-blue tags],
[`lagoon`], [softer Material-inspired slate; vivid sea-glass comments],
[`solarium`], [softer Solarized-inspired blue-green; golden comments and teal tags],
[`spectrum`], [Monokai-inspired near-black and candy colours; golden comments],
[`harvest`], [autumn-inspired near-black earth, ember and leaf green],
[`clay`], [Gruvbox-inspired near-black and earthy brights; amber comments],
[`forge_black`], [pure-black Forge; luminous text and cool slate tags],
[`forge_soft`], [neutral-slate Forge; gentler text, still vivid blue comments],
[`orchard_black`], [pure-black Orchard; luminous garden ink and bright leaf comments],
)
The six classic-inspired ones (`forge` to `clay`) keep a recognisable
syntax identity but are not exact ports; their sources are in
`vendor/themes/`, and they claim no upstream affiliation. The focused
pane's and column's tags shift tone on tone rather than invert: dark
palettes keep dark tags, light ones light tags. The file name in a pane's
path, and `+Search` and the like, take a distinct hue at the same
brightness as the tag text; a terminal's tag tints its #word("Tty") word
instead.
Every native palette sets its own ANSI colours, so a terminal's indexed
colours belong to it; #word("Filter") maps a program's true colours through
the theme too. Normal text, syntax, comments, diagnostics and ANSI
foregrounds keep a contrast of at least 4.5:1 against the page (7:1 in
`ink` and `daybreak`), comments above 5:1; line numbers sit quieter,
between 2.5:1 and 4:1. Tag, focused-tag, selection and search text are held
to the same floors on their own grounds. ANSI black is exempt, since
programs use it as a background. These are checks of the palettes, not a
promise about a program's own escape sequences or the scene effects.
#word("FocusTint") (on) and #word("SyntaxBold") (off) toggle the focused
tag's tint and bold keywords.
= Faithful ports
Well-known themes taken as close to their originals as pardes can draw
them: every colour the original has (page, text, selection, syntax, line
numbers, diagnostics, terminal ANSI) is its own, read out of its files,
and each theme file cites the file and line of every value. pardes has one
colour each for keywords, strings, numbers and comments, so a theme that
splits a kind keeps its main one. A pane's tag is the original's window
bar (vim's `StatusLine`, emacs's `mode-line`) or, in a tabbed editor, its
tab. Where a chrome colour misses one of pardes's floors (rules 1.5:1 off
the page, the focused tag 1.5:1 off the unfocused one on a dark page and
1.25:1 on a light one, tag text 4.5:1), only that colour moves, just far
enough, and the file's header says so; text, syntax and ANSI never move.
An imported theme whose name a port now holds is kept with `_helix` added
(`dracula_helix`).
#pairs(
[Visual Studio Code], [`dark_plus`],
[Solarized], [`solarized_dark`, `solarized_light`],
[Dracula], [`dracula`, `dracula_soft`, `alucard`],
[Monokai], [`monokai`],
[Monokai Pro], [`monokai_pro`, `monokai_pro_classic`, `monokai_pro_machine`, `monokai_pro_octagon`, `monokai_pro_ristretto`, `monokai_pro_spectrum`, `monokai_pro_light`, `monokai_pro_light_sun`],
[Tokyo Night], [`tokyonight_night`, `tokyonight_storm`, `tokyonight_moon`, `tokyonight_day`],
[Rosé Pine], [`rose_pine`, `rose_pine_moon`, `rose_pine_dawn`],
[Catppuccin], [`catppuccin_latte`, `catppuccin_frappe`, `catppuccin_macchiato`, `catppuccin_mocha`],
[Seoul256], [`seoul256_dark_233` to `seoul256_dark_239`, `seoul256_light_252` to `seoul256_light_256`],
[Zenbones], [`zenbones_light`, `zenbones_dark`, `neobones_light`, `neobones_dark`, `vimbones`, `forestbones_light`, `forestbones_dark`, `nordbones`, `rosebones_light`, `rosebones_dark`, `tokyobones_light`, `tokyobones_dark`, `seoulbones_light`, `seoulbones_dark`, `duckbones`, `zenburned`, `zenwritten_light`, `zenwritten_dark`, `kanagawabones`],
[Nord], [`nord`],
[Ayu], [`ayu_dark`, `ayu_mirage`, `ayu_light`],
[Doom One], [`doom_one`, `doom_one_light`],
)
= Making your own <theme-files>
#word("DumpThemes") writes every compiled theme to
`<config dir>/themes/builtin/<name>.zon`. Copy one to `themes/mine.zon`,
change its `.name`, and run `ThemeFile themes/mine.zon` (relative to the
config directory). Where the host reloads files, saving it updates the
theme at once; a malformed save keeps the last good version, and
`Theme <name>` stops the watch. A `ThemeFile` that fails to load says why
in words, a ZON error with its line (`line 3: expected ','`), and changes
nothing: the theme shown stays, and #file("/ctl") and #word("DumpConfig")
still name the file that last loaded, or none. #word("Restore") and
`pardes -l` load a dump's `ThemeFile` again, as a #file("/ctl") write of it
does, and one that fails there changes nothing either. The format is `pardes.Theme` as
`std.zon.stringify` writes it, a complete theme with no inheritance.
The required roles: nullable `bg` and `fg`, `sel_bg`, `sel_fg`, `tag_bg`,
`tag_fg`, `box`, `box_dim`, `kw`, `str`, `num`, `comment`, `lineno`,
`scroll_track`, `scroll_thumb`, and a nullable 16-entry `palette`. Each is
an RGB triple (`.search_bg = .{ 0x57, 0x47, 0x2a }`). The optional roles
take `null`, so older files stay valid:
#pairs(
[`tag_active_bg`, `tag_active_fg`], [the focused pane's tag; a ground closer than 1.25:1 to `tag_bg` is pushed further the way it leans, as far as its text keeps its contrast. Absent: `tag_bg`, `tag_fg`],
[`tag_name_fg`, `tag_active_name_fg`], [the file name's or a terminal's #word("Tty") tint, in normal and focused tags. Absent: the tag's foreground],
[`column_box`, `column_box_dim`], [a column's grip held (and its drag rail), and at rest. Absent: `num`; a mix of `column_box` and `tag_bg`],
[`border`], [quiet separators, lifted to 1.6:1 when under 1.5:1 off the page. Absent: `scroll_track`],
[`empty_col`], [a column with no pane, under its tag (acme: white). Absent: `border`],
[`lineno_active`], [the current line number. Absent: `lineno`],
[`search_bg`, `search_fg`], [search matches, apart from the selection. Absent: `sel_bg`, `sel_fg`],
[`diagnostic_error`, `diagnostic_warning`, `diagnostic_info`, `diagnostic_hint`], [diagnostic text. Absent: `fg`, or `tag_fg` for an inherited foreground],
[`tag_sel_bg`], [a tag's selection ground. Absent: `sel_bg`],
[`sweep_bg`, `sweep_fg`], [three triples each: the select, execute and look sweeps. Absent: `sel_bg` tinted toward `kw`, `str` and `num`, in `sel_fg`],
[`tag_rule`], [the one-pixel rule between a pane's tag and its body. Absent: halfway between `tag_bg` and the page],
[`rule_px`], [pixel shells: the width of the rules between columns and panes and under the column and workspace tags, in logical pixels. Absent: 2],
[`box_border`, `box_dirty`], [the grip as acme's button: a ring of `box_border` when unfocused, filled with `box_dirty` while unsaved. Absent: `box_dim`; `diagnostic_warning`, then `num`],
[`rail_px`], [pixel shells: the scroll column's width at a 17px tagline, scaled with it. Absent: 12, acme's Scrollwid],
[`decor`], [pixel shells: a theme's ornament (lapis's): `page_dots`, `rail_checker`, `tag_border`, `tag_shadow`, `tag_stripe`, `title_shadow`, with their sizes; none of it touches a focus indicator. Absent: none],
)
|