use std::str::FromStr;
use syntect::highlighting::{Color, ScopeSelectors, StyleModifier, Theme, ThemeSettings};
use crate::config;
fn lighten_hex(hex: &str, factor: f32) -> String {
let hex = hex.trim_start_matches('#');
if hex.len() != 6 {
return format!("#{hex}");
}
let r = u8::from_str_radix(&hex[0..2], 16).unwrap_or(0);
let g = u8::from_str_radix(&hex[2..4], 16).unwrap_or(0);
let b = u8::from_str_radix(&hex[4..6], 16).unwrap_or(0);
let blend = |c: u8| (c as f32 + (255.0 - c as f32) * factor).round() as u8;
format!("#{:02X}{:02X}{:02X}", blend(r), blend(g), blend(b))
}
fn darken_hex(hex: &str, factor: f32) -> String {
let hex = hex.trim_start_matches('#');
if hex.len() != 6 {
return format!("#{hex}");
}
let r = u8::from_str_radix(&hex[0..2], 16).unwrap_or(0);
let g = u8::from_str_radix(&hex[2..4], 16).unwrap_or(0);
let b = u8::from_str_radix(&hex[4..6], 16).unwrap_or(0);
let scale = |c: u8| (c as f32 * factor).round() as u8;
format!("#{:02X}{:02X}{:02X}", scale(r), scale(g), scale(b))
}
fn readable_on(hex: &str) -> String {
let hex = hex.trim_start_matches('#');
if hex.len() != 6 {
return "#000000".to_string();
}
let r = u8::from_str_radix(&hex[0..2], 16).unwrap_or(0) as f32;
let g = u8::from_str_radix(&hex[2..4], 16).unwrap_or(0) as f32;
let b = u8::from_str_radix(&hex[4..6], 16).unwrap_or(0) as f32;
let lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
if lum > 140.0 {
"#000000".to_string()
} else {
"#FFFFFF".to_string()
}
}
#[derive(Debug, Clone)]
pub struct ThemeColor {
value: String,
color: Color,
pub bg: String,
pub fg: String,
}
impl From<&str> for ThemeColor {
fn from(hex_color: &str) -> Self {
let color = hex_to_rgba(hex_color);
let (r, g, b) = (color.r, color.g, color.b);
ThemeColor {
value: hex_color.to_owned(),
color,
bg: format!("\x1b[48;2;{};{};{}m", r, g, b),
fg: format!("\x1b[38;2;{};{};{}m", r, g, b),
}
}
}
impl From<&config::Theme> for CustomTheme {
fn from(s: &config::Theme) -> Self {
match s {
config::Theme::Catppuccin => CustomTheme::catppuccin(),
config::Theme::Nord => CustomTheme::nord(),
config::Theme::Monokai => CustomTheme::monokai(),
config::Theme::Dracula => CustomTheme::dracula(),
config::Theme::Gruvbox => CustomTheme::gruvbox(),
config::Theme::OneDark => CustomTheme::one_dark(),
config::Theme::Solarized => CustomTheme::solarized(),
config::Theme::TokyoNight => CustomTheme::tokyo_night(),
config::Theme::MakuraiLight => CustomTheme::makurai_light(),
config::Theme::MakuraiDark => CustomTheme::makurai_dark(),
config::Theme::Ayu => CustomTheme::ayu(),
config::Theme::AyuMirage => CustomTheme::ayu_mirage(),
config::Theme::Github => CustomTheme::github(),
config::Theme::Synthwave => CustomTheme::synthwave(),
config::Theme::Material => CustomTheme::material(),
config::Theme::RosePine => CustomTheme::rose_pine(),
config::Theme::Kanagawa => CustomTheme::kanagawa(),
config::Theme::Vscode => CustomTheme::vscode(),
config::Theme::Everforest => CustomTheme::everforest(),
config::Theme::Autumn => CustomTheme::autumn(),
config::Theme::Spring => CustomTheme::spring(),
}
}
}
#[derive(Debug, Clone)]
pub struct CustomTheme {
pub keyword: ThemeColor,
pub function: ThemeColor,
pub string: ThemeColor,
pub module: ThemeColor,
pub constant: ThemeColor,
pub comment: ThemeColor,
pub foreground: ThemeColor,
pub guide: ThemeColor,
pub background: ThemeColor,
pub surface: ThemeColor,
pub border: ThemeColor,
pub keyword_bg: ThemeColor,
pub red: ThemeColor,
pub green: ThemeColor,
pub blue: ThemeColor,
pub cyan: ThemeColor,
pub yellow: ThemeColor,
pub magenta: ThemeColor,
#[allow(dead_code)]
white: ThemeColor,
pub black: ThemeColor,
}
fn hex_to_rgba(hex: &str) -> Color {
let hex = hex.trim_start_matches('#');
let r = u8::from_str_radix(&hex[0..2], 16).unwrap_or(255);
let g = u8::from_str_radix(&hex[2..4], 16).unwrap_or(255);
let b = u8::from_str_radix(&hex[4..6], 16).unwrap_or(255);
Color { r, g, b, a: 255 }
}
impl CustomTheme {
pub fn autumn() -> Self {
CustomTheme {
keyword: "#fc6501".into(),
keyword_bg: "#2A1A0D".into(),
function: "#fac25a".into(),
string: "#a1cd32".into(),
module: "#fc4c4c".into(),
constant: "#FF6B9D".into(),
comment: "#5C6773".into(),
foreground: "#FFFFFF".into(),
guide: "#2D3640".into(),
background: "#14161f".into(),
surface: "#1E2129".into(),
border: "#5C6773".into(),
red: "#fc4c4c".into(),
green: "#a1cd32".into(),
blue: "#5abffa".into(),
cyan: "#5abffa".into(),
magenta: "#FF6B9D".into(),
yellow: "#fac25a".into(),
white: "#FFFFFF".into(),
black: "#2e3339".into(),
}
}
pub fn spring() -> Self {
CustomTheme {
keyword: "#FFB347".into(),
keyword_bg: "#2A1F0D".into(),
function: "#D4FF59".into(),
string: "#37dbb5".into(),
module: "#66E6FF".into(),
constant: "#D8A5FF".into(),
comment: "#5C6773".into(),
foreground: "#FFFFFF".into(),
guide: "#2D3640".into(),
background: "#14161f".into(),
surface: "#1E2129".into(),
border: "#5C6773".into(),
red: "#FF5555".into(),
green: "#D4FF59".into(),
blue: "#66E6FF".into(),
cyan: "#66E6FF".into(),
magenta: "#D2A6FF".into(),
yellow: "#FFB347".into(),
white: "#FFFFFF".into(),
black: "#2e3339".into(),
}
}
pub fn makurai_dark() -> Self {
CustomTheme {
keyword: "#FF7733".into(),
keyword_bg: "#261810".into(),
function: "#FFEE99".into(),
string: "#95FB79".into(),
module: "#82AAFF".into(),
constant: "#D2A6FF".into(),
comment: "#5C6773".into(),
foreground: "#FFFFFF".into(),
guide: "#2D3640".into(),
background: "#14161f".into(),
surface: "#1E212A".into(),
border: "#5C6773".into(),
red: "#FF5555".into(),
green: "#95FB79".into(),
blue: "#82AAFF".into(),
cyan: "#66D9EF".into(),
magenta: "#FF77FF".into(),
yellow: "#FFEE99".into(),
white: "#FFFFFF".into(),
black: "#14161f".into(),
}
}
pub fn makurai_light() -> Self {
CustomTheme {
keyword: "#E35043".into(),
keyword_bg: "#FDF2F1".into(),
function: "#3D76F3".into(),
string: "#51A150".into(),
module: "#AB31A9".into(),
constant: "#976700".into(),
comment: "#A0A1A7".into(),
foreground: "#323640".into(),
guide: "#D1D5DB".into(),
background: "#f8f8fc".into(),
surface: "#E8E8F0".into(),
border: "#7e8a9e".into(),
red: "#E35043".into(),
green: "#51A150".into(),
blue: "#3D76F3".into(),
cyan: "#00BFCF".into(),
magenta: "#AB31A9".into(),
yellow: "#FFCC00".into(),
white: "#FFFFFF".into(),
black: "#000000".into(),
}
}
pub fn monokai() -> Self {
CustomTheme {
keyword: "#F92672".into(),
keyword_bg: "#2D1A1F".into(),
function: "#A6E22E".into(),
string: "#E6DB74".into(),
module: "#66D9EF".into(),
constant: "#AE81FF".into(),
comment: "#75715E".into(),
foreground: "#F8F8F2".into(),
guide: "#3E3D32".into(),
background: "#272822".into(),
surface: "#343429".into(),
border: "#49483E".into(),
red: "#F92672".into(),
green: "#A6E22E".into(),
blue: "#66D9EF".into(),
cyan: "#66D9EF".into(),
magenta: "#AE81FF".into(),
yellow: "#E6DB74".into(),
white: "#F8F8F2".into(),
black: "#272822".into(),
}
}
pub fn catppuccin() -> Self {
CustomTheme {
keyword: "#CBA6F7".into(),
keyword_bg: "#2A1F33".into(),
function: "#89B4FA".into(),
string: "#A6E3A1".into(),
module: "#89DCEB".into(),
constant: "#F38BA8".into(),
comment: "#7F849C".into(),
foreground: "#CDD6F4".into(),
guide: "#45475A".into(),
background: "#1E1E2E".into(),
surface: "#2A2A3A".into(),
border: "#45475A".into(),
red: "#F38BA8".into(),
green: "#A6E3A1".into(),
blue: "#89B4FA".into(),
cyan: "#89DCEB".into(),
magenta: "#CBA6F7".into(),
yellow: "#F9E2AF".into(),
white: "#CDD6F4".into(),
black: "#1E1E2E".into(),
}
}
pub fn tokyo_night() -> Self {
CustomTheme {
keyword: "#BB9AF7".into(),
keyword_bg: "#261F2D".into(),
function: "#7AA2F7".into(),
string: "#9ECE6A".into(),
module: "#2AC3DE".into(),
constant: "#FF9E64".into(),
comment: "#565F89".into(),
foreground: "#C0CAF5".into(),
guide: "#3B4261".into(),
background: "#1A1B26".into(),
surface: "#24283B".into(),
border: "#414868".into(),
red: "#F7768E".into(),
green: "#9ECE6A".into(),
blue: "#7AA2F7".into(),
cyan: "#2AC3DE".into(),
magenta: "#BB9AF7".into(),
yellow: "#E0AF68".into(),
white: "#C0CAF5".into(),
black: "#1A1B26".into(),
}
}
pub fn dracula() -> Self {
CustomTheme {
keyword: "#FF79C6".into(),
keyword_bg: "#2D1B26".into(),
function: "#50FA7B".into(),
string: "#F1FA8C".into(),
module: "#8BE9FD".into(),
constant: "#BD93F9".into(),
comment: "#6272A4".into(),
foreground: "#F8F8F2".into(),
guide: "#44475A".into(),
background: "#282A36".into(),
surface: "#353746".into(),
border: "#44475A".into(),
red: "#FF5555".into(),
green: "#50FA7B".into(),
blue: "#8BE9FD".into(),
cyan: "#8BE9FD".into(),
magenta: "#FF79C6".into(),
yellow: "#F1FA8C".into(),
white: "#F8F8F2".into(),
black: "#282A36".into(),
}
}
pub fn nord() -> Self {
CustomTheme {
keyword: "#81A1C1".into(),
keyword_bg: "#1C2329".into(),
function: "#88C0D0".into(),
string: "#A3BE8C".into(),
module: "#8FBCBB".into(),
constant: "#B48EAD".into(),
comment: "#616E88".into(),
foreground: "#D8DEE9".into(),
guide: "#434C5E".into(),
background: "#272E37".into(),
surface: "#323A47".into(),
border: "#434C5E".into(),
red: "#BF616A".into(),
green: "#A3BE8C".into(),
blue: "#81A1C1".into(),
cyan: "#88C0D0".into(),
magenta: "#B48EAD".into(),
yellow: "#EBCB8B".into(),
white: "#D8DEE9".into(),
black: "#2E3440".into(),
}
}
pub fn gruvbox() -> Self {
CustomTheme {
keyword: "#FB4934".into(),
keyword_bg: "#2B1A18".into(),
function: "#FABD2F".into(),
string: "#B8BB26".into(),
module: "#83A598".into(),
constant: "#D3869B".into(),
comment: "#928374".into(),
foreground: "#EBDBB2".into(),
guide: "#504945".into(),
background: "#282828".into(),
surface: "#3C3836".into(),
border: "#665C54".into(),
red: "#FB4934".into(),
green: "#B8BB26".into(),
blue: "#83A598".into(),
cyan: "#8EC07C".into(),
magenta: "#D3869B".into(),
yellow: "#FABD2F".into(),
white: "#EBDBB2".into(),
black: "#282828".into(),
}
}
pub fn solarized() -> Self {
CustomTheme {
keyword: "#268BD2".into(),
keyword_bg: "#0A2935".into(),
function: "#B58900".into(),
string: "#2AA198".into(),
module: "#859900".into(),
constant: "#D33682".into(),
comment: "#586E75".into(),
foreground: "#839496".into(),
guide: "#073642".into(),
background: "#002B36".into(),
surface: "#0E3A47".into(),
border: "#586E75".into(),
red: "#DC322F".into(),
green: "#859900".into(),
blue: "#268BD2".into(),
cyan: "#2AA198".into(),
magenta: "#D33682".into(),
yellow: "#B58900".into(),
white: "#EEE8D5".into(),
black: "#002B36".into(),
}
}
pub fn one_dark() -> Self {
CustomTheme {
keyword: "#C678DD".into(),
keyword_bg: "#2A1F2D".into(),
function: "#61AFEF".into(),
string: "#98C379".into(),
module: "#56B6C2".into(),
constant: "#E06C75".into(),
comment: "#5C6370".into(),
foreground: "#ABB2BF".into(),
guide: "#3E4451".into(),
background: "#282C34".into(),
surface: "#353B45".into(),
border: "#3E4451".into(),
red: "#E06C75".into(),
green: "#98C379".into(),
blue: "#61AFEF".into(),
cyan: "#56B6C2".into(),
magenta: "#C678DD".into(),
yellow: "#E5C07B".into(),
white: "#ABB2BF".into(),
black: "#282C34".into(),
}
}
pub fn github() -> Self {
CustomTheme {
keyword: "#FF7B72".into(),
keyword_bg: "#2B1618".into(),
function: "#D2A8FF".into(),
string: "#A5D6FF".into(),
module: "#FFA657".into(),
constant: "#79C0FF".into(),
comment: "#8B949E".into(),
foreground: "#F0F6FC".into(),
guide: "#30363D".into(),
background: "#0D1117".into(),
surface: "#1C2128".into(),
border: "#30363D".into(),
red: "#FF7B72".into(),
green: "#56D364".into(),
blue: "#79C0FF".into(),
cyan: "#A5D6FF".into(),
magenta: "#D2A8FF".into(),
yellow: "#FFA657".into(),
white: "#F0F6FC".into(),
black: "#0D1117".into(),
}
}
pub fn material() -> Self {
CustomTheme {
keyword: "#C792EA".into(),
keyword_bg: "#2F2A37".into(),
function: "#82AAFF".into(),
string: "#C3E88D".into(),
module: "#FFCB6B".into(),
constant: "#F78C6C".into(),
comment: "#676E95".into(),
foreground: "#A6ACCD".into(),
guide: "#4E5579".into(),
background: "#292D3E".into(),
surface: "#32374D".into(),
border: "#444267".into(),
red: "#F07178".into(),
green: "#C3E88D".into(),
blue: "#82AAFF".into(),
cyan: "#89DDFF".into(),
magenta: "#C792EA".into(),
yellow: "#FFCB6B".into(),
white: "#FFFFFF".into(),
black: "#292D3E".into(),
}
}
pub fn ayu() -> Self {
CustomTheme {
keyword: "#FF8F40".into(),
keyword_bg: "#1A1209".into(),
function: "#FFB454".into(),
string: "#AAD94C".into(),
module: "#59C2FF".into(),
constant: "#D2A6FF".into(),
comment: "#ACB6BF8C".into(),
foreground: "#BFBDB6".into(),
guide: "#1F2430".into(),
background: "#0A0E14".into(),
surface: "#151A21".into(),
border: "#1F2430".into(),
red: "#F28779".into(),
green: "#AAD94C".into(),
blue: "#59C2FF".into(),
cyan: "#95E6CB".into(),
magenta: "#D2A6FF".into(),
yellow: "#FFB454".into(),
white: "#BFBDB6".into(),
black: "#0A0E14".into(),
}
}
pub fn ayu_mirage() -> Self {
CustomTheme {
keyword: "#FFA759".into(),
keyword_bg: "#221A0D".into(),
function: "#FFD580".into(),
string: "#BAE67E".into(),
module: "#73D0FF".into(),
constant: "#D4BFFF".into(),
comment: "#5C6773".into(),
foreground: "#CBCCC6".into(),
guide: "#242936".into(),
background: "#1F2430".into(),
surface: "#2A313F".into(),
border: "#343B4C".into(),
red: "#FF6666".into(),
green: "#BAE67E".into(),
blue: "#73D0FF".into(),
cyan: "#95E6CB".into(),
magenta: "#D4BFFF".into(),
yellow: "#FFD580".into(),
white: "#CBCCC6".into(),
black: "#1F2430".into(),
}
}
pub fn synthwave() -> Self {
CustomTheme {
keyword: "#FF7EDB".into(),
keyword_bg: "#2B1929".into(),
function: "#36F9F6".into(),
string: "#E6DB74".into(),
module: "#FE4450".into(),
constant: "#FF8CC8".into(),
comment: "#848077".into(),
foreground: "#F8F8F2".into(),
guide: "#2A2139".into(),
background: "#262335".into(),
surface: "#342949".into(),
border: "#495495".into(),
red: "#FE4450".into(),
green: "#72F1B8".into(),
blue: "#36F9F6".into(),
cyan: "#36F9F6".into(),
magenta: "#FF7EDB".into(),
yellow: "#FEE715".into(),
white: "#F8F8F2".into(),
black: "#262335".into(),
}
}
pub fn rose_pine() -> Self {
CustomTheme {
keyword: "#C4A7E7".into(),
keyword_bg: "#24202E".into(),
function: "#9CCFD8".into(),
string: "#F6C177".into(),
module: "#EBBCBA".into(),
constant: "#EB6F92".into(),
comment: "#6E6A86".into(),
foreground: "#E0DEF4".into(),
guide: "#26233A".into(),
background: "#191724".into(),
surface: "#21202E".into(),
border: "#403D52".into(),
red: "#EB6F92".into(),
green: "#31748F".into(),
blue: "#9CCFD8".into(),
cyan: "#9CCFD8".into(),
magenta: "#C4A7E7".into(),
yellow: "#F6C177".into(),
white: "#E0DEF4".into(),
black: "#191724".into(),
}
}
pub fn kanagawa() -> Self {
CustomTheme {
keyword: "#957FB8".into(),
keyword_bg: "#1E1A22".into(),
function: "#7AA89F".into(),
string: "#98BB6C".into(),
module: "#7FB4CA".into(),
constant: "#D27E99".into(),
comment: "#727169".into(),
foreground: "#DCD7BA".into(),
guide: "#2A2A37".into(),
background: "#1F1F28".into(),
surface: "#2A2A37".into(),
border: "#54546D".into(),
red: "#C34043".into(),
green: "#76946A".into(),
blue: "#7E9CD8".into(),
cyan: "#6A9589".into(),
magenta: "#938AA9".into(),
yellow: "#C0A36E".into(),
white: "#DCD7BA".into(),
black: "#1F1F28".into(),
}
}
pub fn everforest() -> Self {
CustomTheme {
keyword: "#E67E80".into(),
keyword_bg: "#2B1F20".into(),
function: "#A7C080".into(),
string: "#DBBC7F".into(),
module: "#7FBBB3".into(),
constant: "#D699B6".into(),
comment: "#7A8478".into(),
foreground: "#D3C6AA".into(),
guide: "#3D484D".into(),
background: "#2D353B".into(),
surface: "#384148".into(),
border: "#504945".into(),
red: "#E67E80".into(),
green: "#A7C080".into(),
blue: "#7FBBB3".into(),
cyan: "#83C092".into(),
magenta: "#D699B6".into(),
yellow: "#DBBC7F".into(),
white: "#D3C6AA".into(),
black: "#2D353B".into(),
}
}
pub fn vscode() -> Self {
CustomTheme {
keyword: "#569CD6".into(),
keyword_bg: "#142129".into(),
function: "#DCDCAA".into(),
string: "#CE9178".into(),
module: "#4EC9B0".into(),
constant: "#B5CEA8".into(),
comment: "#6A9955".into(),
foreground: "#D4D4D4".into(),
guide: "#404040".into(),
background: "#1E1E1E".into(),
surface: "#2D2D30".into(),
border: "#3E3E42".into(),
red: "#F44747".into(),
green: "#6A9955".into(),
blue: "#569CD6".into(),
cyan: "#4EC9B0".into(),
magenta: "#C586C0".into(),
yellow: "#DCDCAA".into(),
white: "#D4D4D4".into(),
black: "#1E1E1E".into(),
}
}
pub fn to_mermaid_theme(&self) -> mermaid_rs_renderer::Theme {
let mut t = mermaid_rs_renderer::Theme::modern();
t.primary_color = self.surface.value.clone();
t.secondary_color = self.keyword_bg.value.clone();
t.tertiary_color = self.background.value.clone();
t.primary_text_color = self.foreground.value.clone();
t.primary_border_color = self.border.value.clone();
t.line_color = self.foreground.value.clone();
t.edge_label_background = self.background.value.clone();
t.cluster_background = self.keyword_bg.value.clone();
t.cluster_border = self.border.value.clone();
t.background = self.background.value.clone();
t.sequence_actor_fill = self.surface.value.clone();
t.sequence_actor_border = self.border.value.clone();
t.sequence_actor_line = self.comment.value.clone();
t.sequence_note_fill = self.keyword_bg.value.clone();
t.sequence_note_border = self.yellow.value.clone();
t.sequence_activation_fill = self.surface.value.clone();
t.sequence_activation_border = self.border.value.clone();
t.text_color = self.foreground.value.clone();
t.git_colors = [
self.red.value.clone(),
self.blue.value.clone(),
self.green.value.clone(),
self.yellow.value.clone(),
self.magenta.value.clone(),
self.cyan.value.clone(),
darken_hex(&self.red.value, 0.65),
darken_hex(&self.blue.value, 0.65),
];
t.git_inv_colors = [
lighten_hex(&self.red.value, 0.6),
lighten_hex(&self.blue.value, 0.6),
lighten_hex(&self.green.value, 0.6),
lighten_hex(&self.yellow.value, 0.6),
lighten_hex(&self.magenta.value, 0.6),
lighten_hex(&self.cyan.value, 0.6),
lighten_hex(&darken_hex(&self.red.value, 0.65), 0.6),
lighten_hex(&darken_hex(&self.blue.value, 0.65), 0.6),
];
t.git_branch_label_colors = [
readable_on(&t.git_colors[0]),
readable_on(&t.git_colors[1]),
readable_on(&t.git_colors[2]),
readable_on(&t.git_colors[3]),
readable_on(&t.git_colors[4]),
readable_on(&t.git_colors[5]),
readable_on(&t.git_colors[6]),
readable_on(&t.git_colors[7]),
];
t.git_commit_label_color = self.foreground.value.clone();
t.git_commit_label_background = self.surface.value.clone();
t.git_tag_label_color = self.foreground.value.clone();
t.git_tag_label_background = self.surface.value.clone();
t.git_tag_label_border = self.border.value.clone();
t.pie_title_text_color = self.foreground.value.clone();
t.pie_section_text_color = self.foreground.value.clone();
t.pie_legend_text_color = self.foreground.value.clone();
t.pie_stroke_color = self.background.value.clone();
t.pie_outer_stroke_color = self.border.value.clone();
let base = [
&self.red.value,
&self.blue.value,
&self.green.value,
&self.yellow.value,
&self.magenta.value,
&self.cyan.value,
];
t.pie_colors = [
lighten_hex(base[0], 0.45),
darken_hex(base[0], 0.65),
lighten_hex(base[1], 0.45),
darken_hex(base[1], 0.65),
lighten_hex(base[2], 0.45),
darken_hex(base[2], 0.65),
lighten_hex(base[3], 0.45),
darken_hex(base[3], 0.65),
lighten_hex(base[4], 0.45),
darken_hex(base[4], 0.65),
lighten_hex(base[5], 0.45),
darken_hex(base[5], 0.65),
];
t
}
pub fn to_syntect_theme(&self) -> Theme {
let settings = ThemeSettings {
foreground: Some(self.foreground.color),
background: Some(self.surface.color),
guide: Some(self.guide.color),
..Default::default()
};
let mut theme = Theme {
name: None,
author: None,
settings,
scopes: vec![],
};
fn create_selectors(selectors: &str) -> ScopeSelectors {
ScopeSelectors::from_str(selectors).unwrap_or_default()
}
fn create_style(color: Color) -> StyleModifier {
StyleModifier {
foreground: Some(color),
background: None,
font_style: None,
}
}
theme.scopes.push(syntect::highlighting::ThemeItem {
scope: create_selectors("keyword, storage.modifier, storage.type"),
style: create_style(self.keyword.color),
});
theme.scopes.push(syntect::highlighting::ThemeItem {
scope: create_selectors("entity.name.function, support.function, variable.function"),
style: create_style(self.function.color),
});
theme.scopes.push(syntect::highlighting::ThemeItem {
scope: create_selectors(
"module, struct, enum, generic, path, meta.path, entity.name.tag, support.type, meta.import-name",
),
style: create_style(self.module.color),
});
theme.scopes.push(syntect::highlighting::ThemeItem {
scope: create_selectors(
"string, punctuation.string, constant.other.color, punctuation.definition.string",
),
style: create_style(self.string.color),
});
theme.scopes.push(syntect::highlighting::ThemeItem {
scope: create_selectors("constant, keyword.other.unit, support.constant"),
style: create_style(self.constant.color),
});
theme.scopes.push(syntect::highlighting::ThemeItem {
scope: create_selectors("comment, punctuation.comment, punctuation.definition.comment"),
style: create_style(self.comment.color),
});
theme.scopes.push(syntect::highlighting::ThemeItem {
scope: create_selectors(
"variable, operator, punctuation, block, support.type.property-name, punctuation.definition, keyword.operator",
),
style: create_style(self.foreground.color),
});
theme
}
pub fn to_html_style(&self) -> String {
let root_css = format!(
r#"
:root {{
--keyword: {};
--function: {};
--type: {};
--constant: {};
--comment: {};
--foreground: {};
/* UI Colors */
--background: {};
--surface: {};
--border: {};
}}
"#,
self.keyword.value,
self.function.value,
self.module.value,
self.constant.value,
self.comment.value,
self.foreground.value,
self.background.value,
self.surface.value,
self.border.value
);
let full_css = include_str!("../assets/style.css");
format!("{full_css}\n\n{root_css}")
}
}