From 3339eee2dc34d350f7c91b4c860084306196acf0 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Tue, 24 May 2022 19:29:03 +0200 Subject: [PATCH] Make the default macOS theme depend on Dark Mode (#2197) * Make the default macOS theme depend on Dark Mode We frequently get complaints from macOS users that bat does not work on their default macOS terminal background, which is white. Pay the price of slightly increased startup time to get a better default on macOS. To avoid the slightly increased startup time, simply specify a theme explicitly via `--theme`, `BAT_THEME`, or `~/.config/bat`. Note that if there is an error when we check if Dark Mode is enabled, we behave the same as on Windows and Linux; assume that the terminal background is dark. This harmonizes behavior across platforms, and makes bat behave the same as before, when Dark Mode was always assumed to be enabled. * src/assets.rs: Fix typo * Update CHANGELOG.md --- CHANGELOG.md | 2 ++ src/assets.rs | 57 ++++++++++++++++++++++++++++++++++++++ tests/integration_tests.rs | 14 ++++++++++ 3 files changed, 73 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 302f16c1..48d7eaad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Features +- Make the default macOS theme depend on Dark Mode. See #2197, #1746 (@Enselic) + ## Bugfixes ## Other diff --git a/src/assets.rs b/src/assets.rs index 81268433..f87d3934 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -69,10 +69,57 @@ 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 is 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. + */ + #[cfg(target_os = "macos")] + 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 +399,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", + Err(_) => true, + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 4a32de40..70d208e3 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -1427,6 +1427,8 @@ fn ansi_passthrough_emit() { fn ignored_suffix_arg() { bat() .arg("-f") + .arg("--theme") + .arg("Monokai Extended") .arg("-p") .arg("test.json~") .assert() @@ -1436,6 +1438,8 @@ fn ignored_suffix_arg() { bat() .arg("-f") + .arg("--theme") + .arg("Monokai Extended") .arg("-p") .arg("--ignored-suffix=.suffix") .arg("test.json.suffix") @@ -1446,6 +1450,8 @@ fn ignored_suffix_arg() { bat() .arg("-f") + .arg("--theme") + .arg("Monokai Extended") .arg("-p") .arg("test.json.suffix") .assert() @@ -1463,6 +1469,8 @@ fn highlighting_is_skipped_on_long_lines() { bat() .arg("-f") + .arg("--theme") + .arg("Monokai Extended") .arg("-p") .arg("longline.json") .assert() @@ -1482,6 +1490,8 @@ fn all_global_git_config_locations_syntax_mapping_work() { bat() .env("XDG_CONFIG_HOME", fake_home.join(".config").as_os_str()) .arg("-f") + .arg("--theme") + .arg("Monokai Extended") .arg("-p") .arg("git/.config/git/config") .assert() @@ -1492,6 +1502,8 @@ fn all_global_git_config_locations_syntax_mapping_work() { bat() .env("HOME", fake_home.as_os_str()) .arg("-f") + .arg("--theme") + .arg("Monokai Extended") .arg("-p") .arg("git/.config/git/config") .assert() @@ -1502,6 +1514,8 @@ fn all_global_git_config_locations_syntax_mapping_work() { bat() .env("HOME", fake_home.as_os_str()) .arg("-f") + .arg("--theme") + .arg("Monokai Extended") .arg("-p") .arg("git/.gitconfig") .assert()