summaryrefslogtreecommitdiff
path: root/src/themes
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-07-31 02:21:01 -0300
committerGabriel Schneider <[email protected]>2026-08-01 15:02:08 -0300
commit0bfa4615988c0d1bcaa38453375760c60076c5ea (patch)
treefab4f972c10b07739aabc9d772c43e102bce2c07 /src/themes
parentbe404e0d4f91548af6ed600b2fd2027ad8a041c7 (diff)
downloadpardes-0bfa4615988c0d1bcaa38453375760c60076c5ea.tar.gz
pardes-0bfa4615988c0d1bcaa38453375760c60076c5ea.zip
themes: one file each, generated from helix and zed, picked by stepping a list
Each theme is a .zig file of pure data and nothing enumerates them by hand — fold() walks the container's declarations, so a theme is a file and that is the whole registration. Field by field rather than a wholesale coercion, which makes a missing field a compile error that names it. tools/gen_themes.zig reads helix .toml and zed .json out of vendor/themes and emits one .zig each; build.zig reads that directory, so adding a theme is dropping a file in. Output goes to the build cache rather than the tree, so zig owns the freshness check and a deleted source cannot leave a stale theme behind. Vendored, not read from the genizah: the build stays offline. A source it cannot map is a hard error naming the file and the key, never a silently black-on-black theme. ThemeSel is the clever half. Traits gained an `executes` column, so n/N over that buffer hands the whole line to Exec instead of the leading word to Look — both arms the ordinary builtin, so a stepped row does exactly what the matching mouse button on it would. Stepping the list previews each theme live. The trait is a pane property, not an output-pane branch, so any pane whose lines are commands can opt in. Goldens: leader gains SPC t t; theme's fourth NextColor no longer wraps to helix because the ring is fifteen long. New: themesel.
Diffstat (limited to 'src/themes')
-rw-r--r--src/themes/acme.zig29
-rw-r--r--src/themes/dark.zig22
-rw-r--r--src/themes/helix.zig47
3 files changed, 98 insertions, 0 deletions
diff --git a/src/themes/acme.zig b/src/themes/acme.zig
new file mode 100644
index 00000000..925cacfb
--- /dev/null
+++ b/src/themes/acme.zig
@@ -0,0 +1,29 @@
+//! acme's yellow page — the light theme, and the one that has to resolve
+//! `palette` itself. A theme that only dresses the page can leave a child's
+//! ANSI indices alone and let the host answer them; on #ffffea that is how you
+//! get pale yellow `ls` output on pale yellow paper. So the sixteen below are
+//! darkened for paper: index 7 (the "white" a shell writes most of its output
+//! in) is a mid grey, and 15 (bright white) is BLACK, because a program asking
+//! for the brightest color on a light page means "make this stand out".
+pub const theme = .{
+ .name = "acme",
+ .bg = .{ 0xff, 0xff, 0xea },
+ .fg = .{ 0x00, 0x00, 0x00 },
+ .tag_bg = .{ 0xea, 0xff, 0xff },
+ .tag_fg = .{ 0x00, 0x00, 0x00 },
+ .box = .{ 0x6e, 0x4f, 0xd0 },
+ .box_dim = .{ 0x38, 0x3c, 0x54 },
+ .kw = .{ 0x88, 0x22, 0x99 },
+ .str = .{ 0x00, 0x77, 0x33 },
+ .num = .{ 0xa0, 0x52, 0x00 },
+ .comment = .{ 0x55, 0x55, 0x55 },
+ .lineno = .{ 0x99, 0x99, 0x80 },
+ .scroll_track = .{ 0x99, 0x99, 0x4c },
+ .scroll_thumb = .{ 0xff, 0xff, 0xea },
+ .palette = .{
+ .{ 0x00, 0x00, 0x00 }, .{ 0xaa, 0x22, 0x22 }, .{ 0x22, 0x80, 0x22 }, .{ 0x88, 0x66, 0x00 },
+ .{ 0x22, 0x44, 0xbb }, .{ 0x99, 0x33, 0x99 }, .{ 0x11, 0x88, 0x88 }, .{ 0x55, 0x55, 0x55 },
+ .{ 0x88, 0x88, 0x88 }, .{ 0xcc, 0x33, 0x33 }, .{ 0x33, 0xaa, 0x33 }, .{ 0xaa, 0x77, 0x00 },
+ .{ 0x33, 0x55, 0xdd }, .{ 0xbb, 0x44, 0xbb }, .{ 0x22, 0xaa, 0xaa }, .{ 0x00, 0x00, 0x00 },
+ },
+};
diff --git a/src/themes/dark.zig b/src/themes/dark.zig
new file mode 100644
index 00000000..df418982
--- /dev/null
+++ b/src/themes/dark.zig
@@ -0,0 +1,22 @@
+//! pardes's own dark theme, and the boot default until the helix capture
+//! displaced it. It stays in the ring because it is the only one that leaves
+//! `bg`/`fg` NULL: the page keeps the host terminal's own default cell, so
+//! pardes sits inside whatever the surrounding terminal already looks like and
+//! only paints its chrome. Every other theme here dresses the whole page.
+pub const theme = .{
+ .name = "dark",
+ .bg = null,
+ .fg = null,
+ .tag_bg = .{ 0x2c, 0x2a, 0x3e },
+ .tag_fg = .{ 0x96, 0x96, 0x96 },
+ .box = .{ 0x6e, 0x4f, 0xd0 },
+ .box_dim = .{ 0x38, 0x3c, 0x54 },
+ .kw = .{ 0xcc, 0x70, 0xd8 },
+ .str = .{ 0x8a, 0xb8, 0x7a },
+ .num = .{ 0xd0, 0xc0, 0x70 },
+ .comment = .{ 0xf0, 0xf0, 0xf0 },
+ .lineno = .{ 0x5a, 0x5a, 0x5a },
+ .scroll_track = .{ 0x2a, 0x2a, 0x2a },
+ .scroll_thumb = .{ 0x52, 0x52, 0x52 },
+ .palette = null,
+};
diff --git a/src/themes/helix.zig b/src/themes/helix.zig
new file mode 100644
index 00000000..26c156ff
--- /dev/null
+++ b/src/themes/helix.zig
@@ -0,0 +1,47 @@
+//! Copied off the helix the user actually runs: config.toml says
+//! theme = "pardes", i.e. ~/.config/helix/themes/pardes.toml. Every value below
+//! was then PINNED against a real `hx sample.zig` render captured through a
+//! pty, not read off the TOML and hoped for — the SGR runs were 48;2;8;8;8
+//! page, 38;2;189;189;189 text, 38;2;98;98;98 line numbers, 1;38;2;207;135;232
+//! keywords, 38;2;227;199;138 strings AND numeric constants, 38;2;255;255;255
+//! comments. `zig build snap` holds them there (test/snapshots/theme.snap), so
+//! these fifteen numbers are a golden and not taste.
+//!
+//! "dark and minimal" is the half that is not a table. That theme sets no
+//! ui.statusline at all, so helix paints its status row in the page's own
+//! colors: in the capture, rows 8..23 carry one unbroken 48;2;8;8;8 run and the
+//! statusline is told apart from the file by its words alone. pardes cannot go
+//! quite that far — its tag bar is a click target and the gutter is a drag
+//! handle — so chrome lifts by the smallest honest step instead: the theme's
+//! greys are all xterm grayscale-ramp entries (232 #080808, 241 #626262,
+//! 246 #949494, 250 #bdbdbd), so the chrome takes ramp entries too — 233
+//! #121212 for the bars, 238 #444444 for the thumb, 235 #262626 for an
+//! unfocused box. No hue anywhere outside the syntax colors.
+//!
+//! Shape: bg/fg are explicit rather than null, because "just really dark" must
+//! not depend on whose terminal it lands in — but `palette` stays null so a
+//! shell's ANSI indices still resolve to the host's own 16 colors. helix does
+//! the same: it dresses the page it draws and leaves the colors a program emits
+//! alone. Only acme, which has to stay readable on yellow, resolves the palette
+//! itself.
+//!
+//! No imports, and neither has any other theme file: a theme is DATA. The
+//! `.{...}` becomes a pardes.Theme in pardes.zig's `fold`, which is also what
+//! turns a missing field here into a compile error naming it.
+pub const theme = .{
+ .name = "helix",
+ .bg = .{ 0x08, 0x08, 0x08 },
+ .fg = .{ 0xbd, 0xbd, 0xbd },
+ .tag_bg = .{ 0x12, 0x12, 0x12 },
+ .tag_fg = .{ 0x94, 0x94, 0x94 },
+ .box = .{ 0x62, 0x62, 0x62 },
+ .box_dim = .{ 0x26, 0x26, 0x26 },
+ .kw = .{ 0xcf, 0x87, 0xe8 },
+ .str = .{ 0xe3, 0xc7, 0x8a },
+ .num = .{ 0xe3, 0xc7, 0x8a },
+ .comment = .{ 0xff, 0xff, 0xff },
+ .lineno = .{ 0x62, 0x62, 0x62 },
+ .scroll_track = .{ 0x12, 0x12, 0x12 },
+ .scroll_thumb = .{ 0x44, 0x44, 0x44 },
+ .palette = null,
+};