Files
oak-gpui/crates/theme/src/styles/syntax.rs
T
Nate Butler 773ad6bfd1 Document the theme crate (#18690)
This PR enables required documentation for the `theme` crate starts on
documenting it.

The end goal is to have all meaningful documentation in the crate filled
out – However I'm not sure that just adding `#![deny(missing_docs)]` to
the whole crate is the right approach.

I don't know that having 200+ "The color of the _ color" field docs is
useful however–In the short term I've excluded some of the modules that
contain structs with a ton of fields (`colors, `status`, etc.) until we
decide what the right solution here is.

Next steps are to clean up the crate, removing unused modules or those
with low usage in favor of other approaches.

Changes in this PR:
- Enable the `deny(missing_docs)` lint for the `theme` crate 
- Start documenting a subset of the crate.
- Enable `#![allow(missing_docs)]` for some modules.


Release Notes:

- N/A
2024-10-03 10:27:19 -04:00

198 lines
6.1 KiB
Rust

#![allow(missing_docs)]
use std::sync::Arc;
use gpui::{HighlightStyle, Hsla};
#[derive(Debug, PartialEq, Eq, Clone, Default)]
pub struct SyntaxTheme {
pub highlights: Vec<(String, HighlightStyle)>,
}
impl SyntaxTheme {
#[cfg(any(test, feature = "test-support"))]
pub fn new_test(colors: impl IntoIterator<Item = (&'static str, Hsla)>) -> Self {
Self::new_test_styles(colors.into_iter().map(|(key, color)| {
(
key,
HighlightStyle {
color: Some(color),
..Default::default()
},
)
}))
}
#[cfg(any(test, feature = "test-support"))]
pub fn new_test_styles(
colors: impl IntoIterator<Item = (&'static str, HighlightStyle)>,
) -> Self {
Self {
highlights: colors
.into_iter()
.map(|(key, style)| (key.to_owned(), style))
.collect(),
}
}
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()
}
pub fn highlight_id(&self, name: &str) -> Option<u32> {
let ix = self.highlights.iter().position(|entry| entry.0 == name)?;
Some(ix as u32)
}
/// Returns a new [`Arc<SyntaxTheme>`] with the given syntax styles merged in.
pub fn merge(base: Arc<Self>, user_syntax_styles: Vec<(String, HighlightStyle)>) -> Arc<Self> {
if user_syntax_styles.is_empty() {
return base;
}
let mut merged_highlights = base.highlights.clone();
for (name, highlight) in user_syntax_styles {
if let Some((_, existing_highlight)) = merged_highlights
.iter_mut()
.find(|(existing_name, _)| existing_name == &name)
{
existing_highlight.color = highlight.color.or(existing_highlight.color);
existing_highlight.font_weight =
highlight.font_weight.or(existing_highlight.font_weight);
existing_highlight.font_style =
highlight.font_style.or(existing_highlight.font_style);
existing_highlight.background_color = highlight
.background_color
.or(existing_highlight.background_color);
existing_highlight.underline = highlight.underline.or(existing_highlight.underline);
existing_highlight.strikethrough =
highlight.strikethrough.or(existing_highlight.strikethrough);
existing_highlight.fade_out = highlight.fade_out.or(existing_highlight.fade_out);
} else {
merged_highlights.push((name, highlight));
}
}
Arc::new(Self {
highlights: merged_highlights,
})
}
}
#[cfg(test)]
mod tests {
use gpui::FontStyle;
use super::*;
#[test]
fn test_syntax_theme_merge() {
// Merging into an empty `SyntaxTheme` keeps all the user-defined styles.
let syntax_theme = SyntaxTheme::merge(
Arc::new(SyntaxTheme::new_test([])),
vec![
(
"foo".to_string(),
HighlightStyle {
color: Some(gpui::red()),
..Default::default()
},
),
(
"foo.bar".to_string(),
HighlightStyle {
color: Some(gpui::green()),
..Default::default()
},
),
],
);
assert_eq!(
syntax_theme,
Arc::new(SyntaxTheme::new_test([
("foo", gpui::red()),
("foo.bar", gpui::green())
]))
);
// Merging empty user-defined styles keeps all the base styles.
let syntax_theme = SyntaxTheme::merge(
Arc::new(SyntaxTheme::new_test([
("foo", gpui::blue()),
("foo.bar", gpui::red()),
])),
Vec::new(),
);
assert_eq!(
syntax_theme,
Arc::new(SyntaxTheme::new_test([
("foo", gpui::blue()),
("foo.bar", gpui::red())
]))
);
let syntax_theme = SyntaxTheme::merge(
Arc::new(SyntaxTheme::new_test([
("foo", gpui::red()),
("foo.bar", gpui::green()),
])),
vec![(
"foo.bar".to_string(),
HighlightStyle {
color: Some(gpui::yellow()),
..Default::default()
},
)],
);
assert_eq!(
syntax_theme,
Arc::new(SyntaxTheme::new_test([
("foo", gpui::red()),
("foo.bar", gpui::yellow())
]))
);
let syntax_theme = SyntaxTheme::merge(
Arc::new(SyntaxTheme::new_test([
("foo", gpui::red()),
("foo.bar", gpui::green()),
])),
vec![(
"foo.bar".to_string(),
HighlightStyle {
font_style: Some(FontStyle::Italic),
..Default::default()
},
)],
);
assert_eq!(
syntax_theme,
Arc::new(SyntaxTheme::new_test_styles([
(
"foo",
HighlightStyle {
color: Some(gpui::red()),
..Default::default()
}
),
(
"foo.bar",
HighlightStyle {
color: Some(gpui::green()),
font_style: Some(FontStyle::Italic),
..Default::default()
}
)
]))
);
}
}