Autodetect dark/light terminals

Closes #890
pull/894/head
Wilfred Hughes 2025-10-06 22:22:12 +07:00
parent 33570c639a
commit bf335094b8
4 changed files with 49 additions and 2 deletions

@ -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

33
Cargo.lock generated

@ -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"

@ -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"

@ -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<BackgroundColor> {
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 {