From ef7f8c2bd1a644ff29d8cc006abbaf22edb0acab Mon Sep 17 00:00:00 2001 From: Emil Lerch Date: Sat, 27 Jun 2026 10:10:43 -0700 Subject: [PATCH] apply theme to CLI --- src/commands/common.zig | 39 +++++++++++++++++++++++++++++++-------- src/main.zig | 10 +++++++++- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/commands/common.zig b/src/commands/common.zig index 94678fa..f432ccf 100644 --- a/src/commands/common.zig +++ b/src/commands/common.zig @@ -7,15 +7,38 @@ const git = @import("../git.zig"); const framework = @import("framework.zig"); const stderr = @import("../stderr.zig"); pub const fmt = @import("../format.zig"); +const theme = @import("../tui/theme.zig"); -// ── Default CLI colors (match TUI default Monokai theme) ───── -pub const CLR_POSITIVE = [3]u8{ 0x7f, 0xd8, 0x8f }; // gains (TUI .positive) -pub const CLR_NEGATIVE = [3]u8{ 0xe0, 0x6c, 0x75 }; // losses (TUI .negative) -pub const CLR_MUTED = [3]u8{ 0x80, 0x80, 0x80 }; // dim/secondary text (TUI .text_muted) -pub const CLR_HEADER = [3]u8{ 0x9d, 0x7c, 0xd8 }; // section headers (TUI .accent) -pub const CLR_ACCENT = [3]u8{ 0x89, 0xb4, 0xfa }; // info highlights, bar fills (TUI .bar_fill) -pub const CLR_WARNING = [3]u8{ 0xe5, 0xc0, 0x7b }; // stale/manual price indicator (TUI .warning) -pub const CLR_INFO = [3]u8{ 0x56, 0xb6, 0xc2 }; // cyan - secondary legend items (TUI .info) +// ── Active CLI text palette ────────────────────────────────── +// RGB foreground colors for ALL CLI (non-TUI) text output, emitted as +// truecolor ANSI by setFg/printFg. Defaults match the built-in Monokai +// theme; `applyTheme` overwrites them once at startup from the resolved +// `--theme ` (or the default) so the entire CLI - gain/loss, +// headers, muted labels, warnings, accents - honors the user's theme, +// not just the charts. zfin is a single-invocation process and these +// are set once, before any command renders, so process-wide state is +// safe here and avoids threading a palette through every call site. +pub var CLR_POSITIVE = [3]u8{ 0x7f, 0xd8, 0x8f }; // gains (TUI .positive) +pub var CLR_NEGATIVE = [3]u8{ 0xe0, 0x6c, 0x75 }; // losses (TUI .negative) +pub var CLR_MUTED = [3]u8{ 0x80, 0x80, 0x80 }; // dim/secondary text (TUI .text_muted) +pub var CLR_HEADER = [3]u8{ 0x9d, 0x7c, 0xd8 }; // section headers (TUI .accent) +pub var CLR_ACCENT = [3]u8{ 0x89, 0xb4, 0xfa }; // info highlights, bar fills (TUI .bar_fill) +pub var CLR_WARNING = [3]u8{ 0xe5, 0xc0, 0x7b }; // stale/manual price indicator (TUI .warning) +pub var CLR_INFO = [3]u8{ 0x56, 0xb6, 0xc2 }; // cyan - secondary legend items (TUI .info) + +/// Repaint the CLI text palette from a resolved theme. Call once at +/// startup (after `--theme` resolution) so every `CLR_*` reference picks +/// up the user's colors. The field-to-CLR mapping mirrors the comments +/// on the defaults above; keep them in sync. +pub fn applyTheme(th: theme.Theme) void { + CLR_POSITIVE = th.positive; + CLR_NEGATIVE = th.negative; + CLR_MUTED = th.text_muted; + CLR_HEADER = th.accent; + CLR_ACCENT = th.bar_fill; + CLR_WARNING = th.warning; + CLR_INFO = th.info; +} // ── ANSI color helpers ─────────────────────────────────────── diff --git a/src/main.zig b/src/main.zig index e08a296..3c21820 100644 --- a/src/main.zig +++ b/src/main.zig @@ -514,6 +514,14 @@ fn runCli(init: std.process.Init) !u8 { var svc = zfin.DataService.init(io, allocator, config); defer svc.deinit(); + // Resolve the theme once for the whole invocation. It drives BOTH + // the CLI text palette (via cli.applyTheme - gain/loss, headers, + // muted labels, warnings, accents) and chart rendering (via + // RunCtx.chart_theme), so `--theme ` repaints the entire CLI, + // not just the charts. The TUI loads its own theme separately. + const resolved_theme = resolveChartTheme(io, allocator, globals.theme_path); + cli.applyTheme(resolved_theme); + // ── Framework dispatch ─────────────────────────────────────── // // Comptime walk over `command_modules`. Each registered command @@ -550,7 +558,7 @@ fn runCli(init: std.process.Init) !u8 { .color = color, .out = out, .graphics_caps = term_query.detect(io, init.environ_map), - .chart_theme = resolveChartTheme(io, allocator, globals.theme_path), + .chart_theme = resolved_theme, }; const dispatched_args = if (comptime Module.meta.uppercase_first_arg) try cmd_framework.normalizeFirstArg(allocator, cmd_args)