From 0eae962abfff81f2c361ad793024a613a9d89d65 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 26 Oct 2023 16:38:29 +0200 Subject: [PATCH] Represent theme's syntax colors with string keys Co-authored-by: Marshall Bowers --- crates/gpui2/src/style.rs | 11 +++- crates/theme2/src/theme2.rs | 17 +++-- crates/theme2/src/themes/one_dark.rs | 30 +++++++-- crates/theme2/src/themes/rose_pine.rs | 66 ++++++++++++++----- crates/theme2/src/themes/sandcastle.rs | 8 +-- crates/theme_converter/src/main.rs | 85 ++++++------------------- crates/ui2/src/components/breadcrumb.rs | 21 +++--- crates/ui2/src/components/buffer.rs | 2 +- crates/ui2/src/components/toolbar.rs | 8 +-- crates/ui2/src/static_data.rs | 40 ++++++------ 10 files changed, 156 insertions(+), 132 deletions(-) diff --git a/crates/gpui2/src/style.rs b/crates/gpui2/src/style.rs index f443ce1acf85c6df4f9014531902de97fbfc9da3..2544989ebc164d94e52b94bd43b7c3ed5a95c140 100644 --- a/crates/gpui2/src/style.rs +++ b/crates/gpui2/src/style.rs @@ -1,7 +1,7 @@ use crate::{ black, phi, point, rems, AbsoluteLength, BorrowAppContext, BorrowWindow, Bounds, ContentMask, Corners, CornersRefinement, DefiniteLength, Edges, EdgesRefinement, Font, FontFeatures, - FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rems, Result, + FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rems, Result, Rgba, SharedString, Size, SizeRefinement, Styled, TextRun, ViewContext, WindowContext, }; use refineable::{Cascade, Refineable}; @@ -417,3 +417,12 @@ impl From for HighlightStyle { } } } + +impl From for HighlightStyle { + fn from(color: Rgba) -> Self { + Self { + color: Some(color.into()), + ..Default::default() + } + } +} diff --git a/crates/theme2/src/theme2.rs b/crates/theme2/src/theme2.rs index b2f116deb94660880ba52027ef2c3df605f0f147..9a7d58a6c7bf177ff2e6a79db9570cda93681130 100644 --- a/crates/theme2/src/theme2.rs +++ b/crates/theme2/src/theme2.rs @@ -90,13 +90,22 @@ pub struct Theme { #[derive(Clone)] pub struct SyntaxTheme { - pub comment: Hsla, - pub string: Hsla, - pub function: Hsla, - pub keyword: Hsla, pub highlights: Vec<(String, HighlightStyle)>, } +impl SyntaxTheme { + pub fn get(&self, name: &str) -> HighlightStyle { + self.highlights + .iter() + .find_map(|entry| if entry.0 == name { Some(entry.1) } else { None }) + .unwrap_or_default() + } + + pub fn color(&self, name: &str) -> Hsla { + self.get(name).color.unwrap_or_default() + } +} + #[derive(Clone, Copy)] pub struct PlayerTheme { pub cursor: Hsla, diff --git a/crates/theme2/src/themes/one_dark.rs b/crates/theme2/src/themes/one_dark.rs index 991c127c12df3907f3ba3655205375b0968888a5..2f74ab0cd41a72e0986595014a950db279004c40 100644 --- a/crates/theme2/src/themes/one_dark.rs +++ b/crates/theme2/src/themes/one_dark.rs @@ -36,11 +36,31 @@ pub fn one_dark() -> Theme { text_accent: rgba(0x74ade8ff).into(), icon_muted: rgba(0x838994ff).into(), syntax: SyntaxTheme { - comment: rgba(0x5d636fff).into(), - string: rgba(0xa1c181ff).into(), - function: rgba(0x73ade9ff).into(), - keyword: rgba(0xb477cfff).into(), - highlights: vec![], + highlights: vec![ + ("link_text".into(), rgba(0x73ade9ff).into()), + ("punctuation.special".into(), rgba(0xb1574bff).into()), + ("enum".into(), rgba(0xd07277ff).into()), + ("text.literal".into(), rgba(0xa1c181ff).into()), + ("string".into(), rgba(0xa1c181ff).into()), + ("operator".into(), rgba(0x6eb4bfff).into()), + ("constructor".into(), rgba(0x73ade9ff).into()), + ("emphasis.strong".into(), rgba(0xbf956aff).into()), + ("comment".into(), rgba(0x5d636fff).into()), + ("function".into(), rgba(0x73ade9ff).into()), + ("number".into(), rgba(0xbf956aff).into()), + ("property".into(), rgba(0xd07277ff).into()), + ("variable.special".into(), rgba(0xbf956aff).into()), + ("primary".into(), rgba(0xacb2beff).into()), + ("punctuation.list_marker".into(), rgba(0xd07277ff).into()), + ("punctuation".into(), rgba(0xacb2beff).into()), + ("type".into(), rgba(0x6eb4bfff).into()), + ("variant".into(), rgba(0x73ade9ff).into()), + ("constant".into(), rgba(0xdfc184ff).into()), + ("title".into(), rgba(0xd07277ff).into()), + ("boolean".into(), rgba(0xbf956aff).into()), + ("keyword".into(), rgba(0xb477cfff).into()), + ("link_uri".into(), rgba(0x6eb4bfff).into()), + ], }, status_bar: rgba(0x3b414dff).into(), title_bar: rgba(0x3b414dff).into(), diff --git a/crates/theme2/src/themes/rose_pine.rs b/crates/theme2/src/themes/rose_pine.rs index c5087848981d7413a9533b4fbb5210761759b07e..c168b15d5aa6cab8f9be7750dec2fa3acf59276f 100644 --- a/crates/theme2/src/themes/rose_pine.rs +++ b/crates/theme2/src/themes/rose_pine.rs @@ -36,11 +36,23 @@ pub fn rose_pine() -> Theme { text_accent: rgba(0x9bced6ff).into(), icon_muted: rgba(0x74708dff).into(), syntax: SyntaxTheme { - comment: rgba(0x6e6a86ff).into(), - string: rgba(0xf5c177ff).into(), - function: rgba(0xebbcbaff).into(), - keyword: rgba(0x30738fff).into(), - highlights: vec![], + highlights: vec![ + ("variable".into(), rgba(0xe0def4ff).into()), + ("function.method".into(), rgba(0xebbcbaff).into()), + ("title".into(), rgba(0xf5c177ff).into()), + ("type.builtin".into(), rgba(0x9ccfd8ff).into()), + ("type".into(), rgba(0x9ccfd8ff).into()), + ("tag".into(), rgba(0x9ccfd8ff).into()), + ("operator".into(), rgba(0x30738fff).into()), + ("string".into(), rgba(0xf5c177ff).into()), + ("function".into(), rgba(0xebbcbaff).into()), + ("comment".into(), rgba(0x6e6a86ff).into()), + ("keyword".into(), rgba(0x30738fff).into()), + ("boolean".into(), rgba(0xebbcbaff).into()), + ("punctuation".into(), rgba(0x908caaff).into()), + ("link_text".into(), rgba(0x9ccfd8ff).into()), + ("link_uri".into(), rgba(0xebbcbaff).into()), + ], }, status_bar: rgba(0x292738ff).into(), title_bar: rgba(0x292738ff).into(), @@ -128,11 +140,23 @@ pub fn rose_pine_dawn() -> Theme { text_accent: rgba(0x57949fff).into(), icon_muted: rgba(0x706c8cff).into(), syntax: SyntaxTheme { - comment: rgba(0x9893a5ff).into(), - string: rgba(0xea9d34ff).into(), - function: rgba(0xd7827dff).into(), - keyword: rgba(0x276983ff).into(), - highlights: Vec::new(), + highlights: vec![ + ("link_text".into(), rgba(0x55949fff).into()), + ("punctuation".into(), rgba(0x797593ff).into()), + ("string".into(), rgba(0xea9d34ff).into()), + ("variable".into(), rgba(0x575279ff).into()), + ("type".into(), rgba(0x55949fff).into()), + ("comment".into(), rgba(0x9893a5ff).into()), + ("boolean".into(), rgba(0xd7827dff).into()), + ("function.method".into(), rgba(0xd7827dff).into()), + ("operator".into(), rgba(0x276983ff).into()), + ("function".into(), rgba(0xd7827dff).into()), + ("keyword".into(), rgba(0x276983ff).into()), + ("type.builtin".into(), rgba(0x55949fff).into()), + ("tag".into(), rgba(0x55949fff).into()), + ("title".into(), rgba(0xea9d34ff).into()), + ("link_uri".into(), rgba(0xd7827dff).into()), + ], }, status_bar: rgba(0xdcd8d8ff).into(), title_bar: rgba(0xdcd8d8ff).into(), @@ -220,11 +244,23 @@ pub fn rose_pine_moon() -> Theme { text_accent: rgba(0x9bced6ff).into(), icon_muted: rgba(0x85819eff).into(), syntax: SyntaxTheme { - comment: rgba(0x6e6a86ff).into(), - string: rgba(0xf5c177ff).into(), - function: rgba(0xea9a97ff).into(), - keyword: rgba(0x3d8fb0ff).into(), - highlights: Vec::new(), + highlights: vec![ + ("keyword".into(), rgba(0x3d8fb0ff).into()), + ("boolean".into(), rgba(0xea9a97ff).into()), + ("function".into(), rgba(0xea9a97ff).into()), + ("comment".into(), rgba(0x6e6a86ff).into()), + ("title".into(), rgba(0xf5c177ff).into()), + ("link_text".into(), rgba(0x9ccfd8ff).into()), + ("type".into(), rgba(0x9ccfd8ff).into()), + ("type.builtin".into(), rgba(0x9ccfd8ff).into()), + ("punctuation".into(), rgba(0x908caaff).into()), + ("function.method".into(), rgba(0xea9a97ff).into()), + ("tag".into(), rgba(0x9ccfd8ff).into()), + ("variable".into(), rgba(0xe0def4ff).into()), + ("operator".into(), rgba(0x3d8fb0ff).into()), + ("string".into(), rgba(0xf5c177ff).into()), + ("link_uri".into(), rgba(0xea9a97ff).into()), + ], }, status_bar: rgba(0x38354eff).into(), title_bar: rgba(0x38354eff).into(), diff --git a/crates/theme2/src/themes/sandcastle.rs b/crates/theme2/src/themes/sandcastle.rs index 7493ccedd3228fc59e0118102643b67d1af7301c..e8d73bd3514051723c2ccfcd6b36df04d0c9ee4c 100644 --- a/crates/theme2/src/themes/sandcastle.rs +++ b/crates/theme2/src/themes/sandcastle.rs @@ -35,13 +35,7 @@ pub fn sandcastle() -> Theme { text_disabled: rgba(0x827568ff).into(), text_accent: rgba(0x518b8bff).into(), icon_muted: rgba(0xa69782ff).into(), - syntax: SyntaxTheme { - comment: rgba(0xff00ffff).into(), - string: rgba(0xff00ffff).into(), - function: rgba(0xff00ffff).into(), - keyword: rgba(0xff00ffff).into(), - highlights: vec![], - }, + syntax: SyntaxTheme { highlights: vec![] }, status_bar: rgba(0x333944ff).into(), title_bar: rgba(0x333944ff).into(), toolbar: rgba(0x282c33ff).into(), diff --git a/crates/theme_converter/src/main.rs b/crates/theme_converter/src/main.rs index 10c3ff05a34a6a04ff67f9b23e682039f4b66e28..c5e79346d609bfc9ecb8c823a656202627a70ad8 100644 --- a/crates/theme_converter/src/main.rs +++ b/crates/theme_converter/src/main.rs @@ -89,64 +89,6 @@ impl From for PlayerTheme { } } -#[derive(Clone, Copy)] -pub struct SyntaxColor { - pub comment: Hsla, - pub string: Hsla, - pub function: Hsla, - pub keyword: Hsla, -} - -impl Debug for SyntaxColor { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("SyntaxColor") - .field("comment", &HslaPrinter(self.comment)) - .field("string", &HslaPrinter(self.string)) - .field("function", &HslaPrinter(self.function)) - .field("keyword", &HslaPrinter(self.keyword)) - .finish() - } -} - -impl SyntaxColor { - pub fn new(theme: &LegacyTheme) -> Self { - Self { - comment: theme - .syntax - .get("comment") - .cloned() - .unwrap_or_else(|| rgb::(0xff00ff)), - string: theme - .syntax - .get("string") - .cloned() - .unwrap_or_else(|| rgb::(0xff00ff)), - function: theme - .syntax - .get("function") - .cloned() - .unwrap_or_else(|| rgb::(0xff00ff)), - keyword: theme - .syntax - .get("keyword") - .cloned() - .unwrap_or_else(|| rgb::(0xff00ff)), - } - } -} - -impl From for SyntaxTheme { - fn from(value: SyntaxColor) -> Self { - Self { - comment: value.comment, - string: value.string, - keyword: value.keyword, - function: value.function, - highlights: Vec::new(), - } - } -} - fn convert_theme(theme: LegacyTheme) -> Result { let transparent = hsla(0.0, 0.0, 0.0, 0.0); @@ -194,8 +136,13 @@ fn convert_theme(theme: LegacyTheme) -> Result { text_disabled: theme.lowest.base.disabled.foreground, text_accent: theme.lowest.accent.default.foreground, icon_muted: theme.lowest.variant.default.foreground, - syntax: SyntaxColor::new(&theme).into(), - + syntax: SyntaxTheme { + highlights: theme + .syntax + .iter() + .map(|(token, color)| (token.clone(), color.clone().into())) + .collect(), + }, status_bar: theme.lowest.base.default.background, title_bar: theme.lowest.base.default.background, toolbar: theme.highest.base.default.background, @@ -491,11 +438,19 @@ pub struct SyntaxThemePrinter(SyntaxTheme); impl Debug for SyntaxThemePrinter { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("SyntaxTheme") - .field("comment", &HslaPrinter(self.0.comment)) - .field("string", &HslaPrinter(self.0.string)) - .field("function", &HslaPrinter(self.0.function)) - .field("keyword", &HslaPrinter(self.0.keyword)) - .field("highlights", &VecPrinter(&self.0.highlights)) + .field( + "highlights", + &VecPrinter( + &self + .0 + .highlights + .iter() + .map(|(token, highlight)| { + (IntoPrinter(token), HslaPrinter(highlight.color.unwrap())) + }) + .collect(), + ), + ) .finish() } } diff --git a/crates/ui2/src/components/breadcrumb.rs b/crates/ui2/src/components/breadcrumb.rs index 3cba3b7248a668f5499a7da35b739a3c84711422..37660b5b0b95874c8dee3e6fd6732f123e283f8e 100644 --- a/crates/ui2/src/components/breadcrumb.rs +++ b/crates/ui2/src/components/breadcrumb.rs @@ -1,8 +1,8 @@ use std::path::PathBuf; -use gpui2::Div; use crate::prelude::*; use crate::{h_stack, HighlightedText}; +use gpui2::Div; #[derive(Clone)] pub struct Symbol(pub Vec); @@ -15,10 +15,7 @@ pub struct Breadcrumb { impl Breadcrumb { pub fn new(path: PathBuf, symbols: Vec) -> Self { - Self { - path, - symbols, - } + Self { path, symbols } } fn render_separator(&self, cx: &WindowContext) -> Div { @@ -90,7 +87,11 @@ mod stories { Self } - fn render(self, view_state: &mut V, cx: &mut ViewContext) -> impl Component { + fn render( + self, + view_state: &mut V, + cx: &mut ViewContext, + ) -> impl Component { let theme = theme(cx); Story::container(cx) @@ -102,21 +103,21 @@ mod stories { Symbol(vec![ HighlightedText { text: "impl ".to_string(), - color: theme.syntax.keyword, + color: theme.syntax.color("keyword"), }, HighlightedText { text: "BreadcrumbStory".to_string(), - color: theme.syntax.function, + color: theme.syntax.color("function"), }, ]), Symbol(vec![ HighlightedText { text: "fn ".to_string(), - color: theme.syntax.keyword, + color: theme.syntax.color("keyword"), }, HighlightedText { text: "render".to_string(), - color: theme.syntax.function, + color: theme.syntax.color("function"), }, ]), ], diff --git a/crates/ui2/src/components/buffer.rs b/crates/ui2/src/components/buffer.rs index ee8271a94d2f5fe5c23f9781362551479872b714..8250a6b9ee8db07a075b2a72418efe2ebb991259 100644 --- a/crates/ui2/src/components/buffer.rs +++ b/crates/ui2/src/components/buffer.rs @@ -166,7 +166,7 @@ impl Buffer { let line_number_color = if row.current { theme.text } else { - theme.syntax.comment + theme.syntax.get("comment").color.unwrap_or_default() }; h_stack() diff --git a/crates/ui2/src/components/toolbar.rs b/crates/ui2/src/components/toolbar.rs index d3af4485e2685b89442f7b6bd306084d53211e1d..b9da93b55dc293fc6d1d1b348ad3e61af87edc44 100644 --- a/crates/ui2/src/components/toolbar.rs +++ b/crates/ui2/src/components/toolbar.rs @@ -101,21 +101,21 @@ mod stories { Symbol(vec![ HighlightedText { text: "impl ".to_string(), - color: theme.syntax.keyword, + color: theme.syntax.color("keyword"), }, HighlightedText { text: "ToolbarStory".to_string(), - color: theme.syntax.function, + color: theme.syntax.color("function"), }, ]), Symbol(vec![ HighlightedText { text: "fn ".to_string(), - color: theme.syntax.keyword, + color: theme.syntax.color("keyword"), }, HighlightedText { text: "render".to_string(), - color: theme.syntax.function, + color: theme.syntax.color("function"), }, ]), ], diff --git a/crates/ui2/src/static_data.rs b/crates/ui2/src/static_data.rs index 5f6d29a0814095e470b43deb9f1588d6a05fba21..b315bc1f2a85e7af2e8c173e95dced930831baac 100644 --- a/crates/ui2/src/static_data.rs +++ b/crates/ui2/src/static_data.rs @@ -652,11 +652,11 @@ pub fn hello_world_rust_editor_example(cx: &mut WindowContext) -> EditorPane { vec![Symbol(vec![ HighlightedText { text: "fn ".to_string(), - color: theme.syntax.keyword, + color: theme.syntax.color("keyword"), }, HighlightedText { text: "main".to_string(), - color: theme.syntax.function, + color: theme.syntax.color("function"), }, ])], hello_world_rust_buffer_example(&theme), @@ -686,11 +686,11 @@ pub fn hello_world_rust_buffer_rows(theme: &Theme) -> Vec { highlighted_texts: vec![ HighlightedText { text: "fn ".to_string(), - color: theme.syntax.keyword, + color: theme.syntax.color("keyword"), }, HighlightedText { text: "main".to_string(), - color: theme.syntax.function, + color: theme.syntax.color("function"), }, HighlightedText { text: "() {".to_string(), @@ -710,7 +710,7 @@ pub fn hello_world_rust_buffer_rows(theme: &Theme) -> Vec { highlighted_texts: vec![HighlightedText { text: " // Statements here are executed when the compiled binary is called." .to_string(), - color: theme.syntax.comment, + color: theme.syntax.color("comment"), }], }), cursors: None, @@ -733,7 +733,7 @@ pub fn hello_world_rust_buffer_rows(theme: &Theme) -> Vec { line: Some(HighlightedLine { highlighted_texts: vec![HighlightedText { text: " // Print text to the console.".to_string(), - color: theme.syntax.comment, + color: theme.syntax.color("comment"), }], }), cursors: None, @@ -752,7 +752,7 @@ pub fn hello_world_rust_buffer_rows(theme: &Theme) -> Vec { }, HighlightedText { text: "\"Hello, world!\"".to_string(), - color: theme.syntax.string, + color: theme.syntax.color("string"), }, HighlightedText { text: ");".to_string(), @@ -791,11 +791,11 @@ pub fn hello_world_rust_editor_with_status_example(cx: &mut WindowContext) -> Ed vec![Symbol(vec![ HighlightedText { text: "fn ".to_string(), - color: theme.syntax.keyword, + color: theme.syntax.color("keyword"), }, HighlightedText { text: "main".to_string(), - color: theme.syntax.function, + color: theme.syntax.color("function"), }, ])], hello_world_rust_buffer_with_status_example(&theme), @@ -825,11 +825,11 @@ pub fn hello_world_rust_with_status_buffer_rows(theme: &Theme) -> Vec highlighted_texts: vec![ HighlightedText { text: "fn ".to_string(), - color: theme.syntax.keyword, + color: theme.syntax.color("keyword"), }, HighlightedText { text: "main".to_string(), - color: theme.syntax.function, + color: theme.syntax.color("function"), }, HighlightedText { text: "() {".to_string(), @@ -849,7 +849,7 @@ pub fn hello_world_rust_with_status_buffer_rows(theme: &Theme) -> Vec highlighted_texts: vec![HighlightedText { text: "// Statements here are executed when the compiled binary is called." .to_string(), - color: theme.syntax.comment, + color: theme.syntax.color("comment"), }], }), cursors: None, @@ -872,7 +872,7 @@ pub fn hello_world_rust_with_status_buffer_rows(theme: &Theme) -> Vec line: Some(HighlightedLine { highlighted_texts: vec![HighlightedText { text: " // Print text to the console.".to_string(), - color: theme.syntax.comment, + color: theme.syntax.color("comment"), }], }), cursors: None, @@ -891,7 +891,7 @@ pub fn hello_world_rust_with_status_buffer_rows(theme: &Theme) -> Vec }, HighlightedText { text: "\"Hello, world!\"".to_string(), - color: theme.syntax.string, + color: theme.syntax.color("string"), }, HighlightedText { text: ");".to_string(), @@ -938,7 +938,7 @@ pub fn hello_world_rust_with_status_buffer_rows(theme: &Theme) -> Vec line: Some(HighlightedLine { highlighted_texts: vec![HighlightedText { text: "// Marshall and Nate were here".to_string(), - color: theme.syntax.comment, + color: theme.syntax.color("comment"), }], }), cursors: None, @@ -969,7 +969,7 @@ pub fn terminal_buffer_rows(theme: &Theme) -> Vec { highlighted_texts: vec![ HighlightedText { text: "maxdeviant ".to_string(), - color: theme.syntax.keyword, + color: theme.syntax.color("keyword"), }, HighlightedText { text: "in ".to_string(), @@ -977,7 +977,7 @@ pub fn terminal_buffer_rows(theme: &Theme) -> Vec { }, HighlightedText { text: "profaned-capital ".to_string(), - color: theme.syntax.function, + color: theme.syntax.color("function"), }, HighlightedText { text: "in ".to_string(), @@ -985,7 +985,7 @@ pub fn terminal_buffer_rows(theme: &Theme) -> Vec { }, HighlightedText { text: "~/p/zed ".to_string(), - color: theme.syntax.function, + color: theme.syntax.color("function"), }, HighlightedText { text: "on ".to_string(), @@ -993,7 +993,7 @@ pub fn terminal_buffer_rows(theme: &Theme) -> Vec { }, HighlightedText { text: " gpui2-ui ".to_string(), - color: theme.syntax.keyword, + color: theme.syntax.color("keyword"), }, ], }), @@ -1008,7 +1008,7 @@ pub fn terminal_buffer_rows(theme: &Theme) -> Vec { line: Some(HighlightedLine { highlighted_texts: vec![HighlightedText { text: "λ ".to_string(), - color: theme.syntax.string, + color: theme.syntax.color("string"), }], }), cursors: None,