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 side-by-side diffs. Long lines that are not included in the output no
longer affect display. longer affect display.
The `--background` option now supports `auto` to automatically detect
the terminal background color.
## 0.65 (released 23rd September 2025) ## 0.65 (released 23rd September 2025)
### Build ### Build

33
Cargo.lock generated

@ -273,6 +273,7 @@ dependencies = [
"streaming-iterator", "streaming-iterator",
"strsim", "strsim",
"strum", "strum",
"terminal-colorsaurus",
"tikv-jemallocator", "tikv-jemallocator",
"tree-sitter", "tree-sitter",
"tree-sitter-bash", "tree-sitter-bash",
@ -964,6 +965,32 @@ dependencies = [
"winapi-util", "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]] [[package]]
name = "terminal_size" name = "terminal_size"
version = "0.4.1" version = "0.4.1"
@ -1674,6 +1701,12 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e3e6735fcde06432870db8dc9d7e3ab1b93727c14eaef329969426299f28893" checksum = "8e3e6735fcde06432870db8dc9d7e3ab1b93727c14eaef329969426299f28893"
[[package]]
name = "xterm-color"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4de5f056fb9dc8b7908754867544e26145767187aaac5a98495e88ad7cb8a80f"
[[package]] [[package]]
name = "yansi" name = "yansi"
version = "1.0.1" version = "1.0.1"

@ -60,6 +60,7 @@ tree_magic_mini = "3.1.6"
bumpalo = "3.16.0" bumpalo = "3.16.0"
unicode-width = "0.1.9" unicode-width = "0.1.9"
crossterm = { version = "0.28.0", features = ["windows"] } crossterm = { version = "0.28.0", features = ["windows"] }
terminal-colorsaurus = "1.0"
glob = "0.3.1" glob = "0.3.1"
strum = { version = "0.26", features = ["derive"] } strum = { version = "0.26", features = ["derive"] }
hashbrown = "0.14.0" 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") Arg::new("background").long("background")
.value_name("BACKGROUND") .value_name("BACKGROUND")
.env("DFT_BACKGROUND") .env("DFT_BACKGROUND")
.value_parser(["dark", "light"]) .value_parser(["dark", "light", "auto"])
.default_value("dark") .default_value("auto")
.action(ArgAction::Set) .action(ArgAction::Set)
.help("Set the background brightness. Difftastic will prefer brighter colours on dark backgrounds.") .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, "dark" => BackgroundColor::Dark,
"light" => BackgroundColor::Light, "light" => BackgroundColor::Light,
"auto" => detect_background_color().unwrap_or(BackgroundColor::Dark),
_ => unreachable!("clap has already validated the values"), _ => 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 /// Try to work out the width of the terminal we're on, or fall back
/// to a sensible default value. /// to a sensible default value.
fn detect_terminal_width() -> usize { fn detect_terminal_width() -> usize {