global theme flag/theme resolution themes all the things
This commit is contained in:
parent
ef7f8c2bd1
commit
d59555bf92
3 changed files with 42 additions and 39 deletions
|
|
@ -261,9 +261,9 @@ pub const RunCtx = struct {
|
|||
/// `globals.chart_config` to choose kitty-graphics vs braille output.
|
||||
graphics_caps: term_query.Caps = .{},
|
||||
/// Theme for all CLI charts - inline terminal (kitty) charts and
|
||||
/// `--export-chart` PNGs - resolved from the global `--theme <PATH>`
|
||||
/// flag (default: the built-in theme). The TUI loads its own theme
|
||||
/// from `theme.srf` independently.
|
||||
/// `--export-chart` PNGs - resolved once from `--theme <PATH>` (or
|
||||
/// `~/.config/zfin/theme.srf`, else the built-in default). The same
|
||||
/// resolved theme also drives the CLI text palette and the TUI.
|
||||
chart_theme: theme.Theme = theme.default_theme,
|
||||
|
||||
/// Resolve the portfolio pattern(s) (from `-p`/`--portfolio` or
|
||||
|
|
|
|||
63
src/main.zig
63
src/main.zig
|
|
@ -135,10 +135,10 @@ const interactive_help =
|
|||
\\ (e.g. 80x24); `auto` picks Kitty graphics
|
||||
\\ if the terminal supports it, otherwise
|
||||
\\ braille
|
||||
\\ --theme <PATH> Theme file (a `theme.srf`) applied to all
|
||||
\\ charts - inline terminal charts and
|
||||
\\ `--export-chart` PNGs. Default: built-in
|
||||
\\ theme. Generate one with
|
||||
\\ --theme <PATH> Theme file (a `theme.srf`) that skins the
|
||||
\\ whole app: CLI text, charts, and the TUI.
|
||||
\\ Falls back to ~/.config/zfin/theme.srf,
|
||||
\\ then the built-in theme. Generate one with
|
||||
\\ `zfin interactive --default-theme`.
|
||||
\\ --default-keys Print default keybindings as a `keys.srf`
|
||||
\\ template and exit (no TUI launched).
|
||||
|
|
@ -172,9 +172,9 @@ const Globals = struct {
|
|||
refresh_policy: cmd_framework.RefreshPolicy = .auto,
|
||||
/// Chart graphics mode from `--chart` (auto / braille / WxH).
|
||||
chart_config: chart.ChartConfig = .{},
|
||||
/// Theme file from `--theme <PATH>` (a `theme.srf`), applied to all
|
||||
/// charts (inline terminal charts and `--export-chart` PNGs). Null =
|
||||
/// the built-in default theme.
|
||||
/// Theme file from `--theme <PATH>` (a `theme.srf`) that skins the
|
||||
/// whole app - CLI text palette, charts, and the TUI. Null falls
|
||||
/// back to ~/.config/zfin/theme.srf, then the built-in default.
|
||||
theme_path: ?[]const u8 = null,
|
||||
/// Index into args of the first post-global token (the subcommand).
|
||||
cursor: usize,
|
||||
|
|
@ -325,16 +325,28 @@ fn parseGlobals(allocator: std.mem.Allocator, args: []const []const u8) GlobalPa
|
|||
return g;
|
||||
}
|
||||
|
||||
/// Resolve the `--theme <PATH>` flag into a `theme.Theme` for all chart
|
||||
/// rendering (inline terminal charts and `--export-chart` PNGs). A null
|
||||
/// path uses the built-in default; a non-null path that fails to load
|
||||
/// warns and falls back to the default rather than aborting the command.
|
||||
fn resolveChartTheme(io: std.Io, allocator: std.mem.Allocator, path: ?[]const u8) theme.Theme {
|
||||
const p = path orelse return theme.default_theme;
|
||||
return theme.loadFromFile(io, allocator, p) orelse blk: {
|
||||
cli.stderrPrint(io, "Note: could not load --theme file; using the default theme.\n");
|
||||
break :blk theme.default_theme;
|
||||
};
|
||||
/// Resolve the app-wide theme once. Precedence: an explicit
|
||||
/// `--theme <PATH>` (warns + falls back to default if it can't load),
|
||||
/// then `$HOME/.config/zfin/theme.srf` when present, then the built-in
|
||||
/// default. The single resolved value skins everything identically -
|
||||
/// CLI text palette, CLI charts, and the TUI.
|
||||
fn resolveTheme(
|
||||
io: std.Io,
|
||||
allocator: std.mem.Allocator,
|
||||
environ_map: *const std.process.Environ.Map,
|
||||
theme_path: ?[]const u8,
|
||||
) theme.Theme {
|
||||
if (theme_path) |p| {
|
||||
return theme.loadFromFile(io, allocator, p) orelse blk: {
|
||||
cli.stderrPrint(io, "Note: could not load --theme file; using the default theme.\n");
|
||||
break :blk theme.default_theme;
|
||||
};
|
||||
}
|
||||
const home = environ_map.get("HOME") orelse return theme.default_theme;
|
||||
const cfg_path = std.fs.path.join(allocator, &.{ home, ".config", "zfin", "theme.srf" }) catch
|
||||
return theme.default_theme;
|
||||
defer allocator.free(cfg_path);
|
||||
return theme.loadFromFile(io, allocator, cfg_path) orelse theme.default_theme;
|
||||
}
|
||||
|
||||
pub fn main(init: std.process.Init) !u8 {
|
||||
|
|
@ -458,6 +470,13 @@ fn runCli(init: std.process.Init) !u8 {
|
|||
|
||||
const color = @import("format.zig").shouldUseColor(io, init.environ_map, globals.no_color);
|
||||
|
||||
// Resolve the theme once for the entire invocation. This one value
|
||||
// skins the CLI text palette (via cli.applyTheme), CLI charts (via
|
||||
// RunCtx.chart_theme), and the TUI (passed into tui.run) - so
|
||||
// `--theme <PATH>` (or ~/.config/zfin/theme.srf) repaints everything.
|
||||
const resolved_theme = resolveTheme(io, gpa_alloc, init.environ_map, globals.theme_path);
|
||||
cli.applyTheme(resolved_theme);
|
||||
|
||||
const command = args[globals.cursor];
|
||||
const cmd_args: []const []const u8 = @ptrCast(args[globals.cursor + 1 ..]);
|
||||
|
||||
|
|
@ -482,7 +501,7 @@ fn runCli(init: std.process.Init) !u8 {
|
|||
// loader resolve + union-merge the same way the CLI does.
|
||||
// This is the load-bearing fix for "CLI and TUI report
|
||||
// different totals" - there's exactly one code path now.
|
||||
tui.run(io, gpa_alloc, tui_config, globals.portfolio_patterns, globals.watchlist_path, cmd_args, today) catch |err| switch (err) {
|
||||
tui.run(io, gpa_alloc, tui_config, globals.portfolio_patterns, globals.watchlist_path, resolved_theme, cmd_args, today) catch |err| switch (err) {
|
||||
// tui.run already printed an actionable stderr message
|
||||
// for invalid CLI args; surface as exit 1 without a
|
||||
// panic / stack trace.
|
||||
|
|
@ -514,14 +533,6 @@ 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 <PATH>` 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
|
||||
|
|
|
|||
12
src/tui.zig
12
src/tui.zig
|
|
@ -2451,6 +2451,7 @@ pub fn run(
|
|||
config: zfin.Config,
|
||||
portfolio_patterns: []const []const u8,
|
||||
global_watchlist_path: ?[]const u8,
|
||||
app_theme: theme.Theme,
|
||||
args: []const []const u8,
|
||||
today: zfin.Date,
|
||||
) !void {
|
||||
|
|
@ -2516,15 +2517,6 @@ pub fn run(
|
|||
try stderr_writer.interface.flush();
|
||||
}
|
||||
|
||||
const loaded_theme = blk: {
|
||||
const home_opt = if (config.environ_map) |em| em.get("HOME") else null;
|
||||
const home = home_opt orelse break :blk theme.default_theme;
|
||||
const theme_path = std.fs.path.join(allocator, &.{ home, ".config", "zfin", "theme.srf" }) catch
|
||||
break :blk theme.default_theme;
|
||||
defer allocator.free(theme_path);
|
||||
break :blk theme.loadFromFile(io, allocator, theme_path) orelse theme.default_theme;
|
||||
};
|
||||
|
||||
var svc = try allocator.create(zfin.DataService);
|
||||
defer allocator.destroy(svc);
|
||||
svc.* = zfin.DataService.init(io, allocator, config);
|
||||
|
|
@ -2546,7 +2538,7 @@ pub fn run(
|
|||
.config = config,
|
||||
.svc = svc,
|
||||
.keymap = keymap,
|
||||
.theme = loaded_theme,
|
||||
.theme = app_theme,
|
||||
.symbol = symbol,
|
||||
.has_explicit_symbol = has_explicit_symbol,
|
||||
.chart_config = chart_config,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue