use {
crate::app::AppContext,
once_cell::sync::Lazy,
std::path::Path,
syntect::{
easy::{
HighlightLines,
HighlightOptions,
},
highlighting::{
Theme,
ThemeSet,
},
parsing::SyntaxSet,
},
};
static SYNTAXES: &[u8] = include_bytes!("../../resources/syntect/syntaxes.bin");
pub static SYNTAXER: Lazy<Syntaxer> = Lazy::new(Syntaxer::default);
pub struct Syntaxer {
pub syntax_set: SyntaxSet,
pub theme_set: ThemeSet,
}
impl Default for Syntaxer {
fn default() -> Self {
Self {
syntax_set: time!(
Debug,
syntect::dumps::from_uncompressed_data(SYNTAXES).unwrap()
),
theme_set: ThemeSet::load_defaults(),
}
}
}
impl Syntaxer {
pub fn available_themes(&self) -> std::collections::btree_map::Keys<'_, String, Theme> {
self.theme_set.themes.keys()
}
pub fn highlighter_for(
&self,
path: &Path,
con: &AppContext,
) -> Option<HighlightLines<'_>> {
path.extension()
.and_then(|e| e.to_str())
.and_then(|ext| self.syntax_set.find_syntax_by_extension(ext))
.map(|syntax| {
let theme = con.syntax_theme.unwrap_or_default();
let theme = self
.theme_set
.themes
.get(theme.syntect_name())
.unwrap_or_else(|| self.theme_set.themes.iter().next().unwrap().1);
let options = HighlightOptions {
ignore_errors: true,
};
HighlightLines::new(syntax, theme, options)
})
}
}