diff --git a/crates/hyfetch/src/bin/hyfetch.rs b/crates/hyfetch/src/bin/hyfetch.rs index 8daa1b26..a8673a33 100644 --- a/crates/hyfetch/src/bin/hyfetch.rs +++ b/crates/hyfetch/src/bin/hyfetch.rs @@ -87,7 +87,16 @@ fn main() -> Result<()> { }; let color_mode = options.mode.unwrap_or(config.mode); - let theme = config.light_dark; + let auto_detect_light_dark = options + .auto_detect_light_dark + .unwrap_or_else(|| config.auto_detect_light_dark.unwrap_or(false)); + let theme = if auto_detect_light_dark { + let res = det_bg(); + res?.map(|bg| bg.theme()) + .unwrap_or(config.light_dark.unwrap_or_default()) + } else { + config.light_dark.unwrap_or_default() + }; // Check if it's June (pride month) let now = @@ -131,7 +140,12 @@ fn main() -> Result<()> { } else if let Some(lightness) = options.lightness { color_profile.with_lightness(AssignLightness::Replace(lightness)) } else { - color_profile.with_lightness_adaptive(config.lightness(), theme) + color_profile.with_lightness_adaptive( + config + .lightness + .unwrap_or_else(|| Config::default_lightness(theme)), + theme, + ) }; debug!(?color_profile, "lightened color profile"); @@ -187,6 +201,22 @@ fn load_config(path: &PathBuf) -> Result> { Ok(Some(config)) } +fn det_bg() -> Result>, terminal_colorsaurus::Error> { + if !io::stdout().is_terminal() { + return Ok(None); + } + + background_color(QueryOptions::default()) + .map(|terminal_colorsaurus::Color { r, g, b }| Some(Srgb::new(r, g, b).into_format())) + .or_else(|err| { + if matches!(err, terminal_colorsaurus::Error::UnsupportedTerminal) { + Ok(None) + } else { + Err(err) + } + }) +} + /// Creates config interactively. /// /// The config is automatically stored to file. @@ -197,21 +227,10 @@ fn create_config( backend: Backend, debug_mode: bool, ) -> Result { - // Detect terminal environment (doesn't work for all terminal emulators, - // especially on Windows) - let det_bg = if io::stdout().is_terminal() { - match background_color(QueryOptions::default()) { - Ok(bg) => Some(Srgb::::new(bg.r, bg.g, bg.b).into_format::()), - Err(terminal_colorsaurus::Error::UnsupportedTerminal) => None, - Err(err) => { - return Err(err).context("failed to get terminal background color"); - }, - } - } else { - None - }; + let det_bg = det_bg()?; debug!(?det_bg, "detected background color"); let det_ansi = supports_color::on(supports_color::Stream::Stdout).map(|color_level| { + #[allow(clippy::if_same_then_else)] if color_level.has_16m { AnsiMode::Rgb } else if color_level.has_256 { @@ -230,7 +249,7 @@ fn create_config( let asc = get_distro_ascii(distro, backend).context("failed to get distro ascii")?; let asc = asc.to_normalized().context("failed to normalize ascii")?; - let theme = det_bg.map(|bg| bg.theme()).unwrap_or(TerminalTheme::Light); + let theme = det_bg.map(|bg| bg.theme()).unwrap_or_default(); let color_mode = det_ansi.unwrap_or(AnsiMode::Ansi256); let mut title = format!( "Welcome to {logo} Let's set up some colors first.", @@ -1001,7 +1020,8 @@ fn create_config( let config = Config { preset, mode: color_mode, - light_dark: theme, + light_dark: Some(theme), + auto_detect_light_dark: Some(det_bg.is_some()), lightness: Some(lightness), color_align, backend, diff --git a/crates/hyfetch/src/cli_options.rs b/crates/hyfetch/src/cli_options.rs index a4ec50c3..8fcc1816 100644 --- a/crates/hyfetch/src/cli_options.rs +++ b/crates/hyfetch/src/cli_options.rs @@ -31,6 +31,7 @@ pub struct Options { pub print_font_logo: bool, pub test_print: bool, pub ask_exit: bool, + pub auto_detect_light_dark: Option, } pub fn options() -> OptionParser { @@ -170,6 +171,10 @@ BACKEND={{{backends}}}", .help("Ask for input before exiting") .switch() .hide(); + let auto_detect_light_dark = long("auto-detect-light-dark") + .help("Enables hyfetch to detect light/dark terminal background in runtime") + .argument("BOOL") + .optional(); construct!(Options { config, @@ -188,6 +193,7 @@ BACKEND={{{backends}}}", // hidden test_print, ask_exit, + auto_detect_light_dark, }) .to_options() .header( diff --git a/crates/hyfetch/src/models.rs b/crates/hyfetch/src/models.rs index 30571f1f..65fa69f4 100644 --- a/crates/hyfetch/src/models.rs +++ b/crates/hyfetch/src/models.rs @@ -9,7 +9,8 @@ use crate::types::{AnsiMode, Backend, TerminalTheme}; pub struct Config { pub preset: Preset, pub mode: AnsiMode, - pub light_dark: TerminalTheme, + pub auto_detect_light_dark: Option, + pub light_dark: Option, pub lightness: Option, pub color_align: ColorAlignment, pub backend: Backend, @@ -31,11 +32,6 @@ impl Config { }, } } - - pub fn lightness(&self) -> Lightness { - self.lightness - .unwrap_or_else(|| Self::default_lightness(self.light_dark)) - } } mod args_serde { diff --git a/crates/hyfetch/src/types.rs b/crates/hyfetch/src/types.rs index 5094eaef..e4f5aa77 100644 --- a/crates/hyfetch/src/types.rs +++ b/crates/hyfetch/src/types.rs @@ -36,6 +36,12 @@ pub enum TerminalTheme { Dark, } +impl Default for TerminalTheme { + fn default() -> Self { + Self::Light + } +} + #[derive( Copy, Clone,