zed/zed/src/theme.rs

156 lines
3.7 KiB
Rust
Raw Normal View History

mod highlight_map;
mod theme_registry;
use anyhow::Result;
use gpui::{
color::Color,
elements::{ContainerStyle, LabelStyle},
fonts::TextStyle,
};
use serde::{Deserialize, Deserializer};
use std::collections::HashMap;
pub use highlight_map::*;
pub use theme_registry::*;
pub const DEFAULT_THEME_NAME: &'static str = "dark";
#[derive(Debug, Default, Deserialize)]
pub struct Theme {
#[serde(default)]
pub name: String,
pub workspace: Workspace,
pub chat_panel: ChatPanel,
pub selector: Selector,
pub editor: Editor,
#[serde(deserialize_with = "deserialize_syntax_theme")]
pub syntax: Vec<(String, TextStyle)>,
}
#[derive(Debug, Default, Deserialize)]
pub struct Workspace {
pub background: Color,
pub tab: Tab,
pub active_tab: Tab,
pub sidebar: ContainerStyle,
pub sidebar_icon: SidebarIcon,
pub active_sidebar_icon: SidebarIcon,
}
#[derive(Debug, Default, Deserialize)]
pub struct Tab {
#[serde(flatten)]
pub container: ContainerStyle,
#[serde(flatten)]
pub label: LabelStyle,
pub icon_close: Color,
pub icon_dirty: Color,
pub icon_conflict: Color,
}
#[derive(Debug, Default, Deserialize)]
pub struct SidebarIcon {
pub color: Color,
}
#[derive(Debug, Default, Deserialize)]
pub struct ChatPanel {
2021-08-25 22:22:14 +00:00
#[serde(flatten)]
pub container: ContainerStyle,
pub message: ChatMessage,
}
#[derive(Debug, Default, Deserialize)]
pub struct ChatMessage {
pub body: TextStyle,
2021-08-25 22:22:14 +00:00
pub sender: ContainedLabel,
pub timestamp: ContainedLabel,
}
#[derive(Debug, Default, Deserialize)]
pub struct Selector {
#[serde(flatten)]
pub container: ContainerStyle,
#[serde(flatten)]
pub label: LabelStyle,
2021-08-25 22:22:14 +00:00
pub item: ContainedLabel,
pub active_item: ContainedLabel,
}
#[derive(Debug, Default, Deserialize)]
2021-08-25 22:22:14 +00:00
pub struct ContainedLabel {
#[serde(flatten)]
pub container: ContainerStyle,
#[serde(flatten)]
pub label: LabelStyle,
}
#[derive(Debug, Deserialize)]
pub struct Editor {
pub background: Color,
pub gutter_background: Color,
pub active_line_background: Color,
pub line_number: Color,
pub line_number_active: Color,
pub text: Color,
pub replicas: Vec<Replica>,
}
#[derive(Clone, Copy, Debug, Default, Deserialize)]
pub struct Replica {
pub cursor: Color,
pub selection: Color,
}
impl Theme {
pub fn highlight_style(&self, id: HighlightId) -> TextStyle {
self.syntax
.get(id.0 as usize)
.map(|entry| entry.1.clone())
.unwrap_or_else(|| TextStyle {
color: self.editor.text,
font_properties: Default::default(),
})
}
#[cfg(test)]
pub fn highlight_name(&self, id: HighlightId) -> Option<&str> {
self.syntax.get(id.0 as usize).map(|e| e.0.as_str())
}
}
impl Default for Editor {
fn default() -> Self {
Self {
background: Default::default(),
gutter_background: Default::default(),
active_line_background: Default::default(),
line_number: Default::default(),
line_number_active: Default::default(),
text: Default::default(),
replicas: vec![Replica::default()],
}
}
}
pub fn deserialize_syntax_theme<'de, D>(
deserializer: D,
) -> Result<Vec<(String, TextStyle)>, D::Error>
where
D: Deserializer<'de>,
{
let mut result = Vec::<(String, TextStyle)>::new();
let syntax_data: HashMap<String, TextStyle> = Deserialize::deserialize(deserializer)?;
for (key, style) in syntax_data {
match result.binary_search_by(|(needle, _)| needle.cmp(&key)) {
Ok(i) | Err(i) => {
result.insert(i, (key, style));
}
}
}
Ok(result)
}