use crate::config::{Config, THEME_FILE_NAME};
use crate::mode;
use crate::terminal::utils::Terminal;
use crate::terminal::{osc, utils};
use crate::theme::model::ThemeLayer;
use crate::theme::parse;
use crate::theme::resolve::{PALETTE_EXTENSION, Resolver};
use crate::walk;
use anyhow::Result;
use std::io::{Write, stdout};
pub fn run(config: &Config) -> Result<()> {
let Some(terminal) = utils::detect() else {
return Ok(());
};
let cwd = std::env::current_dir()?;
let resolver = Resolver::new(config.base_theme_dir.clone());
let current_mode = mode::detect();
if let Some(rc_path) = walk::find_nearest(&cwd, THEME_FILE_NAME) {
let theme = resolver.resolve(&rc_path, current_mode)?;
let mut out = stdout().lock();
if theme.is_empty() {
osc::emit_reset(&mut out, terminal)?;
} else {
emit_themed(&mut out, terminal, theme, config)?;
}
return Ok(());
}
if let Some(default_name) = &config.default_theme {
let palette_path =
config
.base_theme_dir
.join(format!("{}.{}", default_name.as_str(), PALETTE_EXTENSION));
if palette_path.exists() {
let palette = parse::parse_palette_file(&palette_path)?;
if !palette.layer.is_empty() {
let mut out = stdout().lock();
emit_themed(&mut out, terminal, palette.layer, config)?;
return Ok(());
}
}
}
let mut out = stdout().lock();
osc::emit_reset(&mut out, terminal)?;
Ok(())
}
fn emit_themed<W: Write>(
out: &mut W,
terminal: Terminal,
mut layer: ThemeLayer,
config: &Config,
) -> Result<()> {
if config.tab_follows_window {
layer.fill_tab_from_bg();
}
osc::emit(out, terminal, &layer)?;
if config.tab_follows_window && layer.tab_bg.is_none() {
osc::emit_tab_reset(out, terminal)?;
}
Ok(())
}