mod catppuccin; pub(crate) mod syntax; use gpui::{Background, Rgba}; #[allow(unused_imports)] pub use syntax::{HIGHLIGHT_NAMES, ThemeSyntax, ThemeSyntaxHighlight}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub enum ThemeMode { Light, #[default] Dark, } #[derive(Debug, Clone, Copy, PartialEq)] pub struct Theme { pub id: &'static str, pub name: &'static str, pub mode: ThemeMode, pub colors: ThemeColors, pub syntax: ThemeSyntax, } impl Default for Theme { fn default() -> Self { ThemeFamily::default().theme(ThemeMode::default()) } } #[derive(Debug, Clone, Copy, PartialEq)] pub struct ThemeColors { pub background: Rgba, pub surface: Rgba, pub surface_elevated: Rgba, pub surface_button: Background, pub surface_chrome: Rgba, pub surface_hover: Rgba, pub surface_active: Rgba, pub border: Rgba, pub border_muted: Rgba, pub border_strong: Rgba, pub focus_ring: Rgba, pub text: Rgba, pub text_muted: Rgba, pub text_subtle: Rgba, pub text_disabled: Rgba, pub icon_muted: Rgba, pub link: Rgba, pub link_hover: Rgba, pub code_bg: Rgba, pub code_border: Rgba, pub selection_bg: Rgba, pub selection_border: Rgba, pub accent_fg: Rgba, pub accent_muted: Rgba, pub accent_border: Rgba, pub accent_solid: Rgba, pub accent_on_solid: Rgba, pub success_fg: Rgba, pub success_muted: Rgba, pub success_border: Rgba, pub success_solid: Rgba, pub success_on_solid: Rgba, pub warning_fg: Rgba, pub warning_muted: Rgba, pub warning_border: Rgba, pub warning_solid: Rgba, pub warning_on_solid: Rgba, pub danger_fg: Rgba, pub danger_muted: Rgba, pub danger_border: Rgba, pub danger_solid: Rgba, pub danger_on_solid: Rgba, pub info_fg: Rgba, pub info_muted: Rgba, pub info_border: Rgba, pub info_solid: Rgba, pub info_on_solid: Rgba, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] #[allow(dead_code)] pub enum ThemeFamily { #[default] Catppuccin, } #[allow(dead_code)] impl ThemeFamily { pub const ALL: [Self; 1] = [Self::Catppuccin]; pub const fn id(self) -> &'static str { match self { | Self::Catppuccin => catppuccin::FAMILY_ID, } } pub const fn label(self) -> &'static str { match self { | Self::Catppuccin => catppuccin::FAMILY_LABEL, } } pub const fn variant(self, mode: ThemeMode) -> ThemeVariant { match (self, mode) { | (Self::Catppuccin, ThemeMode::Light) => ThemeVariant::CatppuccinLatte, | (Self::Catppuccin, ThemeMode::Dark) => ThemeVariant::CatppuccinMocha, } } pub fn theme(self, mode: ThemeMode) -> Theme { self.variant(mode).theme() } pub fn theme_for_appearance(self, appearance: gpui::WindowAppearance) -> Theme { self.theme(appearance.into()) } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] #[allow(dead_code)] pub enum ThemeVariant { CatppuccinLatte, #[default] CatppuccinMocha, } #[allow(dead_code)] impl ThemeVariant { pub const ALL: [Self; 2] = [Self::CatppuccinLatte, Self::CatppuccinMocha]; pub const fn family(self) -> ThemeFamily { match self { | Self::CatppuccinLatte | Self::CatppuccinMocha => ThemeFamily::Catppuccin, } } pub const fn mode(self) -> ThemeMode { match self { | Self::CatppuccinLatte => ThemeMode::Light, | Self::CatppuccinMocha => ThemeMode::Dark, } } pub const fn label(self) -> &'static str { match self { | Self::CatppuccinLatte => catppuccin::LATTE_LABEL, | Self::CatppuccinMocha => catppuccin::MOCHA_LABEL, } } pub fn theme(self) -> Theme { match self { | Self::CatppuccinLatte => catppuccin::latte(), | Self::CatppuccinMocha => catppuccin::mocha(), } } } impl From for ThemeMode { fn from(value: gpui::WindowAppearance) -> Self { match value { | gpui::WindowAppearance::Light | gpui::WindowAppearance::VibrantLight => { ThemeMode::Light } | gpui::WindowAppearance::Dark | gpui::WindowAppearance::VibrantDark => ThemeMode::Dark, } } } impl From for Theme { fn from(value: gpui::WindowAppearance) -> Self { ThemeFamily::default().theme(value.into()) } }