use crate::config::ThemeConfig;
use ratatui::prelude::{Color, Style};
pub struct Theme {
pub cmd_regular: Style,
pub cmd_regular_pipe: Style,
pub cmd_regular_current: Style,
pub cmd_highlight: Style,
pub cmd_highlight_pipe: Style,
pub cmd_highlight_current: Style,
pub cmd_quoted: Style,
pub cmd_invalid: Style,
pub cmd_diff_base: Style,
pub output_highlight: Style,
pub output_highlight_current: Style,
pub line_nums: Style,
pub popup: Style,
pub diff_addition: Style,
pub diff_deletion: Style,
pub diff_equal: Style,
}
impl Theme {
pub fn from_config(config: &ThemeConfig) -> Self {
Theme {
cmd_regular: style_from_config(&config.cmd_regular),
cmd_regular_pipe: style_from_config(&config.cmd_regular_pipe),
cmd_regular_current: style_from_config(&config.cmd_regular_current),
cmd_highlight: style_from_config(&config.cmd_highlight),
cmd_highlight_pipe: style_from_config(&config.cmd_highlight_pipe),
cmd_highlight_current: style_from_config(&config.cmd_highlight_current),
cmd_quoted: style_from_config(&config.cmd_quoted),
cmd_invalid: style_from_config(&config.cmd_invalid),
cmd_diff_base: style_from_config(&config.cmd_diff_base),
output_highlight: style_from_config(&config.output_highlight),
output_highlight_current: style_from_config(&config.output_highlight_current),
line_nums: style_from_config(&config.line_nums),
popup: style_from_config(&config.popup),
diff_addition: style_from_config(&config.diff_addition),
diff_deletion: style_from_config(&config.diff_deletion),
diff_equal: style_from_config(&config.diff_equal),
}
}
}
fn style_from_config(sc: &crate::config::StyleConfig) -> Style {
let mut s = Style::default();
if let Some(c) = sc.fg.as_deref().and_then(parse_color) {
s = s.fg(c);
}
if let Some(c) = sc.bg.as_deref().and_then(parse_color) {
s = s.bg(c);
}
if sc.bold.unwrap_or(false) {
s = s.bold();
}
if sc.italic.unwrap_or(false) {
s = s.italic();
}
if sc.underlined.unwrap_or(false) {
s = s.underlined();
}
if sc.dim.unwrap_or(false) {
s = s.dim();
}
s
}
fn parse_color(s: &str) -> Option<Color> {
match s.to_lowercase().as_str() {
"black" => Some(Color::Black),
"red" => Some(Color::Red),
"green" => Some(Color::Green),
"yellow" => Some(Color::Yellow),
"blue" => Some(Color::Blue),
"magenta" => Some(Color::Magenta),
"cyan" => Some(Color::Cyan),
"white" => Some(Color::White),
"gray" | "grey" => Some(Color::Gray),
"darkgray" | "dark_gray" => Some(Color::DarkGray),
"lightred" | "light_red" => Some(Color::LightRed),
"lightgreen" | "light_green" => Some(Color::LightGreen),
"lightyellow" | "light_yellow" => Some(Color::LightYellow),
"lightblue" | "light_blue" => Some(Color::LightBlue),
"lightmagenta" | "light_magenta" => Some(Color::LightMagenta),
"lightcyan" | "light_cyan" => Some(Color::LightCyan),
s if s.starts_with('#') && s.len() == 7 => {
let r = u8::from_str_radix(&s[1..3], 16).ok()?;
let g = u8::from_str_radix(&s[3..5], 16).ok()?;
let b = u8::from_str_radix(&s[5..7], 16).ok()?;
Some(Color::Rgb(r, g, b))
}
s => s.parse::<u8>().ok().map(Color::Indexed),
}
}