Skip to main content

linesmith_core/runtime/
themes.rs

1//! Runtime theme registry construction. Built-ins are always loaded;
2//! user themes under `$XDG_CONFIG_HOME/linesmith/themes/` are
3//! best-effort.
4
5use std::path::{Path, PathBuf};
6
7use crate::data_context::xdg::{resolve_subdir, XdgEnv, XdgScope};
8use crate::theme::ThemeRegistry;
9
10/// `$XDG_CONFIG_HOME/linesmith/themes/` (with `$HOME` fallback) per
11/// the cascade in [`crate::data_context::xdg::resolve_subdir`].
12/// `None` when neither env var is populated.
13#[must_use]
14pub fn user_themes_dir(env: &XdgEnv) -> Option<PathBuf> {
15    resolve_subdir(env, XdgScope::Config, "themes")
16}
17
18/// Build a [`ThemeRegistry`] from built-ins plus user themes
19/// discovered under `user_themes_dir`. Pass `None` to skip user-
20/// theme loading entirely (test harnesses, no XDG/HOME env). The
21/// loader is best-effort — `on_warn` is called for theme-loader
22/// diagnostics: malformed files, name collisions (built-in
23/// override, duplicate user theme), and unreadable directory
24/// entries. Pass `|_| {}` to discard.
25pub fn build_theme_registry(
26    user_themes_dir: Option<&Path>,
27    on_warn: impl FnMut(&str),
28) -> ThemeRegistry {
29    let mut registry = ThemeRegistry::with_built_ins();
30    if let Some(dir) = user_themes_dir {
31        registry = registry.with_user_themes(dir, on_warn);
32    }
33    registry
34}