[PR] Auto detect light/dark mode, changing the theme accordingly (#380)
* disable clippy lint * fmt * move detect bg into a function * auto detect light/dark opt * auto detect dark cli opt * optional light-dark * cli opt * nicer looking output * [-] Revert code style changes * [-] Revert code style changes * [-] Revert code style changes * [-] Revert * make the default theme dark --------- Co-authored-by: Azalea <22280294+hykilpikonna@users.noreply.github.com>
This commit is contained in:
parent
8a536c30f0
commit
0cc6ddbca8
4 changed files with 51 additions and 23 deletions
|
|
@ -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<Option<Config>> {
|
|||
Ok(Some(config))
|
||||
}
|
||||
|
||||
fn det_bg() -> Result<Option<Srgb<u8>>, 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<Config> {
|
||||
// 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::<u16>::new(bg.r, bg.g, bg.b).into_format::<u8>()),
|
||||
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.",
|
||||
|
|
@ -1002,7 +1021,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,
|
||||
|
|
|
|||
|
|
@ -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<bool>,
|
||||
}
|
||||
|
||||
pub fn options() -> OptionParser<Options> {
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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<bool>,
|
||||
pub light_dark: Option<TerminalTheme>,
|
||||
pub lightness: Option<Lightness>,
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,12 @@ pub enum TerminalTheme {
|
|||
Dark,
|
||||
}
|
||||
|
||||
impl Default for TerminalTheme {
|
||||
fn default() -> Self {
|
||||
Self::Dark
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Copy,
|
||||
Clone,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue