on master help sign in
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

commit3339eee2dc34d350f7c91b4c860084306196acf0 authorMartin Nordholts <enselic@gmail.com> dateTue 24 May 2022, 19:29 (4 years ago) parente9f8370
3 files changed+73
unifiedsplit
CHANGELOG.md+2 src/assets.rs+57 tests/integration_tests.rs+14
CHANGELOG.md+2
@@ -2,6 +2,8 @@
22
33## Features
44
5+- Make the default macOS theme depend on Dark Mode. See #2197, #1746 (@Enselic)
6+
57## Bugfixes
68
79## Other
src/assets.rs+57
@@ -69,10 +69,57 @@ impl HighlightingAssets {
6969 }
7070 }
7171
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.
7293 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 {
73112 "Monokai Extended"
74113 }
75114
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+
76123 pub fn from_cache(cache_path: &Path) -> Result<Self> {
77124 Ok(HighlightingAssets::new(
78125 SerializedSyntaxSet::FromFile(cache_path.join("syntaxes.bin")),
@@ -352,6 +399,16 @@ fn asset_from_cache<T: serde::de::DeserializeOwned>(
352399 .map_err(|_| format!("Could not parse cached {}", description).into())
353400}
354401
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+
355412#[cfg(test)]
356413mod tests {
357414 use super::*;
tests/integration_tests.rs+14
@@ -1427,6 +1427,8 @@ fn ansi_passthrough_emit() {
14271427fn ignored_suffix_arg() {
14281428 bat()
14291429 .arg("-f")
1430+ .arg("--theme")
1431+ .arg("Monokai Extended")
14301432 .arg("-p")
14311433 .arg("test.json~")
14321434 .assert()
@@ -1436,6 +1438,8 @@ fn ignored_suffix_arg() {
14361438
14371439 bat()
14381440 .arg("-f")
1441+ .arg("--theme")
1442+ .arg("Monokai Extended")
14391443 .arg("-p")
14401444 .arg("--ignored-suffix=.suffix")
14411445 .arg("test.json.suffix")
@@ -1446,6 +1450,8 @@ fn ignored_suffix_arg() {
14461450
14471451 bat()
14481452 .arg("-f")
1453+ .arg("--theme")
1454+ .arg("Monokai Extended")
14491455 .arg("-p")
14501456 .arg("test.json.suffix")
14511457 .assert()
@@ -1463,6 +1469,8 @@ fn highlighting_is_skipped_on_long_lines() {
14631469
14641470 bat()
14651471 .arg("-f")
1472+ .arg("--theme")
1473+ .arg("Monokai Extended")
14661474 .arg("-p")
14671475 .arg("longline.json")
14681476 .assert()
@@ -1482,6 +1490,8 @@ fn all_global_git_config_locations_syntax_mapping_work() {
14821490 bat()
14831491 .env("XDG_CONFIG_HOME", fake_home.join(".config").as_os_str())
14841492 .arg("-f")
1493+ .arg("--theme")
1494+ .arg("Monokai Extended")
14851495 .arg("-p")
14861496 .arg("git/.config/git/config")
14871497 .assert()
@@ -1492,6 +1502,8 @@ fn all_global_git_config_locations_syntax_mapping_work() {
14921502 bat()
14931503 .env("HOME", fake_home.as_os_str())
14941504 .arg("-f")
1505+ .arg("--theme")
1506+ .arg("Monokai Extended")
14951507 .arg("-p")
14961508 .arg("git/.config/git/config")
14971509 .assert()
@@ -1502,6 +1514,8 @@ fn all_global_git_config_locations_syntax_mapping_work() {
15021514 bat()
15031515 .env("HOME", fake_home.as_os_str())
15041516 .arg("-f")
1517+ .arg("--theme")
1518+ .arg("Monokai Extended")
15051519 .arg("-p")
15061520 .arg("git/.gitconfig")
15071521 .assert()