From bf335094b89c81d7c2f4ad222664d97aa436a890 Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Mon, 6 Oct 2025 22:22:12 +0100 Subject: [PATCH] Autodetect dark/light terminals Closes #890 --- CHANGELOG.md | 3 +++ Cargo.lock | 33 +++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/options.rs | 14 ++++++++++++-- 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d3b30d0f..31ee3d85b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ Difftastic is now smarter about calculating the display width for side-by-side diffs. Long lines that are not included in the output no longer affect display. +The `--background` option now supports `auto` to automatically detect +the terminal background color. + ## 0.65 (released 23rd September 2025) ### Build diff --git a/Cargo.lock b/Cargo.lock index 4de037d96..0f93b153c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -273,6 +273,7 @@ dependencies = [ "streaming-iterator", "strsim", "strum", + "terminal-colorsaurus", "tikv-jemallocator", "tree-sitter", "tree-sitter-bash", @@ -964,6 +965,32 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "terminal-colorsaurus" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f7226dad4b1817567c1e2f5d453897ef36abe79def7783af3fa241a694e30b3" +dependencies = [ + "cfg-if", + "libc", + "memchr", + "mio", + "terminal-trx", + "windows-sys 0.59.0", + "xterm-color", +] + +[[package]] +name = "terminal-trx" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975b4233aefa1b02456d5e53b22c61653c743e308c51cf4181191d8ce41753ab" +dependencies = [ + "cfg-if", + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "terminal_size" version = "0.4.1" @@ -1674,6 +1701,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e3e6735fcde06432870db8dc9d7e3ab1b93727c14eaef329969426299f28893" +[[package]] +name = "xterm-color" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4de5f056fb9dc8b7908754867544e26145767187aaac5a98495e88ad7cb8a80f" + [[package]] name = "yansi" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index a025d9248..5a71b2a58 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,6 +60,7 @@ tree_magic_mini = "3.1.6" bumpalo = "3.16.0" unicode-width = "0.1.9" crossterm = { version = "0.28.0", features = ["windows"] } +terminal-colorsaurus = "1.0" glob = "0.3.1" strum = { version = "0.26", features = ["derive"] } hashbrown = "0.14.0" diff --git a/src/options.rs b/src/options.rs index d7e553600..dca3b928c 100644 --- a/src/options.rs +++ b/src/options.rs @@ -201,8 +201,8 @@ json: Output the results as a machine-readable JSON array with an element per fi Arg::new("background").long("background") .value_name("BACKGROUND") .env("DFT_BACKGROUND") - .value_parser(["dark", "light"]) - .default_value("dark") + .value_parser(["dark", "light", "auto"]) + .default_value("auto") .action(ArgAction::Set) .help("Set the background brightness. Difftastic will prefer brighter colours on dark backgrounds.") ) @@ -782,6 +782,7 @@ pub(crate) fn parse_args() -> Mode { { "dark" => BackgroundColor::Dark, "light" => BackgroundColor::Light, + "auto" => detect_background_color().unwrap_or(BackgroundColor::Dark), _ => unreachable!("clap has already validated the values"), }; @@ -960,6 +961,15 @@ pub(crate) fn parse_args() -> Mode { } } +/// Try to detect the terminal background color. +fn detect_background_color() -> Option { + match terminal_colorsaurus::theme_mode(terminal_colorsaurus::QueryOptions::default()) { + Ok(terminal_colorsaurus::ThemeMode::Dark) => Some(BackgroundColor::Dark), + Ok(terminal_colorsaurus::ThemeMode::Light) => Some(BackgroundColor::Light), + Err(_) => None, + } +} + /// Try to work out the width of the terminal we're on, or fall back /// to a sensible default value. fn detect_terminal_width() -> usize {