@@ -4,7 +4,7 @@ use std::path::Path;
44
55use once_cell::unsync::OnceCell;
66
7−use syntect::highlighting::{Theme, ThemeSet};
7+use syntect::highlighting::Theme;
88use syntect::parsing::{SyntaxReference, SyntaxSet};
99
1010use path_abs::PathAbs;
@@ -15,6 +15,8 @@ use crate::syntax_mapping::ignored_suffixes::IgnoredSuffixes;
1515use crate::syntax_mapping::MappingTarget;
1616use crate::{bat_warning, SyntaxMapping};
1717
18+use lazy_theme_set::LazyThemeSet;
19+
1820use serialized_syntax_set::*;
1921
2022#[cfg(feature = "build-assets")]
@@ -23,6 +25,7 @@ pub use crate::assets::build_assets::*;
2325pub(crate) mod assets_metadata;
2426#[cfg(feature = "build-assets")]
2527mod build_assets;
28+mod lazy_theme_set;
2629mod serialized_syntax_set;
2730
2831#[derive(Debug)]
@@ -30,7 +33,7 @@ pub struct HighlightingAssets {
3033 syntax_set_cell: OnceCell<SyntaxSet>,
3134 serialized_syntax_set: SerializedSyntaxSet,
3235
33− theme_set: ThemeSet,
36+ theme_set: LazyThemeSet,
3437 fallback_theme: Option<&'static str>,
3538}
3639
@@ -43,11 +46,17 @@ pub struct SyntaxReferenceInSet<'a> {
4346/// Compress for size of ~700 kB instead of ~4600 kB at the cost of ~30% longer deserialization time
4447pub(crate) const COMPRESS_SYNTAXES: bool = true;
4548
46−/// Compress for size of ~20 kB instead of ~200 kB at the cost of ~30% longer deserialization time
47−pub(crate) const COMPRESS_THEMES: bool = true;
49+/// We don't want to compress our [LazyThemeSet] since the lazy-loaded themes
50+/// within it are already compressed, and compressing another time just makes
51+/// performance suffer
52+pub(crate) const COMPRESS_THEMES: bool = false;
53+
54+/// Compress for size of ~40 kB instead of ~200 kB without much difference in
55+/// performance due to lazy-loading
56+pub(crate) const COMPRESS_LAZY_THEMES: bool = true;
4857
4958impl HighlightingAssets {
50− fn new(serialized_syntax_set: SerializedSyntaxSet, theme_set: ThemeSet) -> Self {
59+ fn new(serialized_syntax_set: SerializedSyntaxSet, theme_set: LazyThemeSet) -> Self {
5160 HighlightingAssets {
5261 syntax_set_cell: OnceCell::new(),
5362 serialized_syntax_set,
@@ -95,12 +104,12 @@ impl HighlightingAssets {
95104 Ok(self.get_syntax_set()?.syntaxes())
96105 }
97106
98− fn get_theme_set(&self) -> &ThemeSet {
107+ fn get_theme_set(&self) -> &LazyThemeSet {
99108 &self.theme_set
100109 }
101110
102111 pub fn themes(&self) -> impl Iterator<Item = &str> {
103− self.get_theme_set().themes.keys().map(|s| s.as_ref())
112+ self.get_theme_set().themes()
104113 }
105114
106115 /// Use [Self::get_syntax_for_path] instead
@@ -175,7 +184,7 @@ impl HighlightingAssets {
175184 }
176185
177186 pub(crate) fn get_theme(&self, theme: &str) -> &Theme {
178− match self.get_theme_set().themes.get(theme) {
187+ match self.get_theme_set().get(theme) {
179188 Some(theme) => theme,
180189 None => {
181190 if theme == "ansi-light" || theme == "ansi-dark" {
@@ -185,8 +194,9 @@ impl HighlightingAssets {
185194 if !theme.is_empty() {
186195 bat_warning!("Unknown theme '{}', using default.", theme)
187196 }
188− &self.get_theme_set().themes
189− [self.fallback_theme.unwrap_or_else(|| Self::default_theme())]
197+ self.get_theme_set()
198+ .get(self.fallback_theme.unwrap_or_else(|| Self::default_theme()))
199+ .expect("something is very wrong if the default theme is missing")
190200 }
191201 }
192202 }
@@ -291,7 +301,7 @@ pub(crate) fn get_serialized_integrated_syntaxset() -> &'static [u8] {
291301 include_bytes!("../assets/syntaxes.bin")
292302}
293303
294−pub(crate) fn get_integrated_themeset() -> ThemeSet {
304+pub(crate) fn get_integrated_themeset() -> LazyThemeSet {
295305 from_binary(include_bytes!("../assets/themes.bin"), COMPRESS_THEMES)
296306}
297307