@@ -43,8 +43,9 @@ pub struct SyntaxReferenceInSet<'a> {
4343 pub syntax_set: &'a SyntaxSet,
4444}
4545
46−/// Compress for size of ~700 kB instead of ~4600 kB at the cost of ~30% longer deserialization time
47−pub(crate) const COMPRESS_SYNTAXES: bool = true;
46+/// Lazy-loaded syntaxes are already compressed, and we don't want to compress
47+/// already compressed data.
48+pub(crate) const COMPRESS_SYNTAXES: bool = false;
4849
4950/// We don't want to compress our [LazyThemeSet] since the lazy-loaded themes
5051/// within it are already compressed, and compressing another time just makes
@@ -68,10 +69,57 @@ impl HighlightingAssets {
6869 }
6970 }
7071
72+ /// The default theme.
73+ ///
74+ /// ### Windows and Linux
75+ ///
76+ /// Windows and most Linux distributions has a dark terminal theme by
77+ /// default. On these platforms, this function always returns a theme that
78+ /// looks good on a dark background.
79+ ///
80+ /// ### macOS
81+ ///
82+ /// On macOS the default terminal background is light, but it is common that
83+ /// Dark Mode is active, which makes the terminal background dark. On this
84+ /// platform, the default theme depends on
85+ /// ```bash
86+ /// defaults read -globalDomain AppleInterfaceStyle
87+ /// ````
88+ /// To avoid the overhead of the check on macOS, simply specify a theme
89+ /// explicitly via `--theme`, `BAT_THEME`, or `~/.config/bat`.
90+ ///
91+ /// See <https://github.com/sharkdp/bat/issues/1746> and
92+ /// <https://github.com/sharkdp/bat/issues/1928> for more context.
7193 pub fn default_theme() -> &'static str {
94+ #[cfg(not(target_os = "macos"))]
95+ {
96+ Self::default_dark_theme()
97+ }
98+ #[cfg(target_os = "macos")]
99+ {
100+ if macos_dark_mode_active() {
101+ Self::default_dark_theme()
102+ } else {
103+ Self::default_light_theme()
104+ }
105+ }
106+ }
107+
108+ /**
109+ * The default theme that looks good on a dark background.
110+ */
111+ fn default_dark_theme() -> &'static str {
72112 "Monokai Extended"
73113 }
74114
115+ /**
116+ * The default theme that looks good on a light background.
117+ */
118+ #[cfg(target_os = "macos")]
119+ fn default_light_theme() -> &'static str {
120+ "Monokai Extended Light"
121+ }
122+
75123 pub fn from_cache(cache_path: &Path) -> Result<Self> {
76124 Ok(HighlightingAssets::new(
77125 SerializedSyntaxSet::FromFile(cache_path.join("syntaxes.bin")),
@@ -351,6 +399,16 @@ fn asset_from_cache<T: serde::de::DeserializeOwned>(
351399 .map_err(|_| format!("Could not parse cached {}", description).into())
352400}
353401
402+#[cfg(target_os = "macos")]
403+fn macos_dark_mode_active() -> bool {
404+ let mut defaults_cmd = std::process::Command::new("defaults");
405+ defaults_cmd.args(&["read", "-globalDomain", "AppleInterfaceStyle"]);
406+ match defaults_cmd.output() {
407+ Ok(output) => output.stdout == b"Dark\n",
408+ Err(_) => true,
409+ }
410+}
411+
354412#[cfg(test)]
355413mod tests {
356414 use super::*;
@@ -581,13 +639,22 @@ mod tests {
581639 }
582640
583641 #[test]
584− fn syntax_detection_is_case_sensitive() {
642+ fn syntax_detection_is_case_insensitive() {
585643 let mut test = SyntaxDetectionTest::new();
586644
587− assert_ne!(test.syntax_for_file("README.MD"), "Markdown");
645+ assert_eq!(test.syntax_for_file("README.md"), "Markdown");
646+ assert_eq!(test.syntax_for_file("README.mD"), "Markdown");
647+ assert_eq!(test.syntax_for_file("README.Md"), "Markdown");
648+ assert_eq!(test.syntax_for_file("README.MD"), "Markdown");
649+
650+ // Adding a mapping for "MD" in addition to "md" should not break the mapping
588651 test.syntax_mapping
589652 .insert("*.MD", MappingTarget::MapTo("Markdown"))
590653 .ok();
654+
655+ assert_eq!(test.syntax_for_file("README.md"), "Markdown");
656+ assert_eq!(test.syntax_for_file("README.mD"), "Markdown");
657+ assert_eq!(test.syntax_for_file("README.Md"), "Markdown");
591658 assert_eq!(test.syntax_for_file("README.MD"), "Markdown");
592659 }
593660