diff options
| author | Gabriel Schneider <[email protected]> | 2026-07-27 01:43:12 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-08-01 15:02:07 -0300 |
| commit | f0e498832a1a4f92d5fdbc3fc643a3dba1dd9df9 (patch) | |
| tree | 47bebbd93e2288f33253de28d797e79ced81c348 /src/pardes.zig | |
| parent | 42c0524b94d67caebbf71cd8a82d7690380195fa (diff) | |
| download | pardes-f0e498832a1a4f92d5fdbc3fc643a3dba1dd9df9.tar.gz pardes-f0e498832a1a4f92d5fdbc3fc643a3dba1dd9df9.zip | |
helix theme, now the default: near-black page, chrome one grey-ramp step off it
Colors lifted from the user's own helix theme (~/.config/helix/themes/pardes.toml,
pinned against a real hx render through a pty). Theme gains box/box_dim so a
restrained theme can turn the accent down; the hardcoded gray.* overlay greys
were the dark theme's own fields spelled twice and are gone. The old default is
still one NextColor away.
Diffstat (limited to 'src/pardes.zig')
| -rw-r--r-- | src/pardes.zig | 75 |
1 files changed, 62 insertions, 13 deletions
diff --git a/src/pardes.zig b/src/pardes.zig index 61174877..017892aa 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -210,8 +210,6 @@ pub const bash_rc = // ---- theme ---- -pub const accent = [3]u8{ 0x6e, 0x4f, 0xd0 }; -pub const accent_dim = [3]u8{ 0x38, 0x3c, 0x54 }; // per-button selection highlight: distinct muted colors per mouse button const SEL_BG = [3][3]u8{ .{ 0x2c, 0x46, 0x74 }, .{ 0x2c, 0x60, 0x38 }, .{ 0x64, 0x2c, 0x58 } }; const sel_fg = [3]u8{ 0xd2, 0xd2, 0xd2 }; @@ -220,18 +218,23 @@ const msel_bg = [3]u8{ 0x4a, 0x3a, 0x1e }; const msel_fg = [3]u8{ 0xd8, 0xc8, 0xa8 }; const UNDO_MAX = 256; const EDIT_UNDO_MAX = 64; // terminal snapshots copy the edit buffer; cap tighter -const gray = struct { - const bar = [3]u8{ 0x2a, 0x2a, 0x2a }; // dim bars (overlay bg) - const mid = [3]u8{ 0x52, 0x52, 0x52 }; // move preview - const txt = [3]u8{ 0x96, 0x96, 0x96 }; // muted text -}; +/// Everything a theme repaints. `bg`/`fg` null = leave the host terminal's own +/// default cell showing (the native-dark shape); `palette` null = let a child's +/// ANSI indices reach the host untranslated. The gutter's move box lives here +/// too: it used to be a pair of module constants, but a theme that wants to be +/// restrained has to be able to turn the accent DOWN, and the box is the one +/// piece of loud chrome on screen. The overlay/drag greys that were also +/// hardcoded turned out to be the dark theme's own scroll_track/lineno/tag_fg +/// spelled a second time, so they read those fields now instead. pub const Theme = struct { name: []const u8, bg: ?[3]u8, fg: ?[3]u8, tag_bg: [3]u8, tag_fg: [3]u8, + box: [3]u8, // move box, focused pane + box_dim: [3]u8, // move box, everything else kw: [3]u8, str: [3]u8, num: [3]u8, @@ -243,12 +246,56 @@ pub const Theme = struct { }; pub const themes = [_]Theme{ + // 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. + // + // "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-light, which has to stay readable on + // yellow, resolves the palette itself. + .{ + .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, + }, .{ .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 }, @@ -264,6 +311,8 @@ pub const themes = [_]Theme{ .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 }, @@ -5330,9 +5379,9 @@ pub const Pardes = struct { if (p.movePlacement(d.id, d.cur_x, d.cur_y)) |placement| { var col: u16 = p.col_x[placement.preview_col]; while (col < p.col_x[placement.preview_col] + p.col_w[placement.preview_col]) : (col += 1) { - s.set(col, placement.row, "╌", .{ .fg = .{ .rgb = gray.mid } }); + s.set(col, placement.row, "╌", .{ .fg = .{ .rgb = th.lineno } }); } - s.set(d.cur_x, placement.row, "▌", .{ .fg = .{ .rgb = gray.mid } }); + s.set(d.cur_x, placement.row, "▌", .{ .fg = .{ .rgb = th.lineno } }); } }, .none, .select => { @@ -5398,12 +5447,12 @@ pub const Pardes = struct { s.set(ox, by, "│", .{}); s.set(ox + ow - 1, by, "│", .{}); } - s.fill(ox + 1, TOPBAR_H + 1, ow - 2, oh - 2, .{ .bg = .{ .rgb = gray.bar } }); + s.fill(ox + 1, TOPBAR_H + 1, ow - 2, oh - 2, .{ .bg = .{ .rgb = th.scroll_track } }); var lines = std.mem.splitScalar(u8, text, '\n'); var ly: u16 = TOPBAR_H + 1; while (lines.next()) |line| : (ly += 1) { if (ly >= TOPBAR_H + oh - 1) break; - _ = s.print(ox + 1, ly, ow - 2, line, .{ .fg = .{ .rgb = gray.txt } }); + _ = s.print(ox + 1, ly, ow - 2, line, .{ .fg = .{ .rgb = th.tag_fg } }); } } }; @@ -5471,7 +5520,7 @@ pub const Pardes = struct { // thumbless gutter so it reads like any other pane. if (pane.image != null) { p.drawImage(pane, r, tx, tw); - const box_bg2 = if (active) accent else accent_dim; + const box_bg2 = if (active) th.box else th.box_dim; s.fill(r.x, r.y, GUTTER, BOX_H, .{ .bg = .{ .rgb = box_bg2 } }); if (r.h > BOX_H) s.fill(r.x, r.y + BOX_H, GUTTER, r.h - BOX_H, .{ .bg = .{ .rgb = th.scroll_track } }); return; @@ -5654,7 +5703,7 @@ pub const Pardes = struct { } // gutter: move box on top, scrollbar track + thumb below - const box_bg = if (active) accent else accent_dim; + const box_bg = if (active) th.box else th.box_dim; s.fill(r.x, r.y, GUTTER, BOX_H, .{ .bg = .{ .rgb = box_bg } }); if (r.h > BOX_H) { s.fill(r.x, r.y + BOX_H, GUTTER, r.h - BOX_H, .{ .bg = .{ .rgb = th.scroll_track } }); |
