diff --git a/src/assets.rs b/src/assets.rs index 8126843373..75661a29b4 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -69,10 +69,56 @@ impl HighlightingAssets { } } + /// The default theme. + /// + /// ### Windows and Linux + /// + /// Windows and most Linux distributions has a dark terminal theme by + /// default. On these platforms, this function always returns a theme that + /// looks good on a dark background. + /// + /// ### macOS + /// + /// On macOS the default terminal background is light, but it is common that + /// Dark Mode active, which makes the terminal background dark. On this + /// platform, the default theme depends on + /// ```bash + /// defaults read -globalDomain AppleInterfaceStyle + /// ```` + /// To avoid the overhead of the check on macOS, simply specify a theme + /// explicitly via `--theme`, `BAT_THEME`, or `~/.config/bat`. + /// + /// See and + /// for more context. pub fn default_theme() -> &'static str { + #[cfg(not(target_os = "macos"))] + { + Self::default_dark_theme() + } + #[cfg(target_os = "macos")] + { + if macos_dark_mode_active() { + Self::default_dark_theme() + } else { + Self::default_light_theme() + } + } + } + + /** + * The default theme that looks good on a dark background. + */ + fn default_dark_theme() -> &'static str { "Monokai Extended" } + /** + * The default theme that looks good on a light background. + */ + fn default_light_theme() -> &'static str { + "Monokai Extended Light" + } + pub fn from_cache(cache_path: &Path) -> Result { Ok(HighlightingAssets::new( SerializedSyntaxSet::FromFile(cache_path.join("syntaxes.bin")), @@ -352,6 +398,16 @@ fn asset_from_cache( .map_err(|_| format!("Could not parse cached {}", description).into()) } +#[cfg(target_os = "macos")] +fn macos_dark_mode_active() -> bool { + let mut defaults_cmd = std::process::Command::new("defaults"); + defaults_cmd.args(&["read", "-globalDomain", "AppleInterfaceStyle"]); + match defaults_cmd.output() { + Ok(output) => output.stdout == b"Dark\n", + _ => false, + } +} + #[cfg(test)] mod tests { use super::*;