Skip to content

Commit

Permalink
✨ Add support for CLITHEME
Browse files Browse the repository at this point in the history
  • Loading branch information
bash committed Dec 27, 2024
1 parent 8382808 commit b4dba96
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 10 deletions.
13 changes: 4 additions & 9 deletions crates/terminal-colorsaurus/examples/theme.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
//! This example shows how to detect if the terminal uses
//! a dark-on-light or a light-on-dark theme.
use terminal_colorsaurus::{color_palette, ColorScheme, Error, QueryOptions};
use terminal_colorsaurus::{color_scheme, ColorScheme, Error, QueryOptions};

fn main() -> Result<(), display::DisplayAsDebug<Error>> {
let colors = color_palette(QueryOptions::default())?;

let theme = match colors.color_scheme() {
let theme = color_scheme(QueryOptions::default())?;
let theme_name = match theme {
ColorScheme::Dark => "dark",
ColorScheme::Light => "light",
};

println!(
"{theme}, fg: {}, bg: {}",
colors.foreground.perceived_lightness(),
colors.background.perceived_lightness()
);
println!("{theme_name}");

Ok(())
}
Expand Down
36 changes: 36 additions & 0 deletions crates/terminal-colorsaurus/src/cli_theme.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//! Implements <https://wiki.tau.garden/cli-theme/>.
use std::env;
use std::ffi::OsStr;
use std::os::unix::ffi::OsStrExt;

pub(crate) fn cli_theme() -> Option<CliTheme> {
let raw = env::var_os("CLITHEME")?;
let preference = parse_preference(&raw);
Some(CliTheme { preference })
}

fn parse_preference(raw: &OsStr) -> CliThemePreference {
if raw == "dark" || raw.as_bytes().starts_with(b"dark:") {
CliThemePreference::Dark
} else if raw == "light" || raw.as_bytes().starts_with(b"light:") {
CliThemePreference::Light
} else {
CliThemePreference::Auto
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub(crate) struct CliTheme {
pub(crate) preference: CliThemePreference,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[allow(clippy::exhaustive_enums)]
pub(crate) enum CliThemePreference {
Dark,
Light,
#[default]
Auto,
}
13 changes: 12 additions & 1 deletion crates/terminal-colorsaurus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ cfg_if! {
mod xparsecolor;
mod xterm;
use xterm as imp;
mod cli_theme;
} else {
mod unsupported;
use unsupported as imp;
Expand Down Expand Up @@ -130,6 +131,7 @@ impl ColorPalette {

/// Result used by this library.
pub type Result<T> = std::result::Result<T, Error>;
use cli_theme::CliThemePreference;
pub use error::Error;

/// Options to be used with [`foreground_color`] and [`background_color`].
Expand Down Expand Up @@ -172,10 +174,19 @@ impl Default for QueryOptions {
}

/// Detects if the terminal is dark or light.
///
/// This function supports the [`CLITHEME`] environment variable
/// and skips detection if it is set to either **dark** or **light**.
///
/// [`CLITHEME`]: https://wiki.tau.garden/cli-theme/
#[doc = include_str!("../doc/caveats.md")]
#[doc(alias = "theme")]
pub fn color_scheme(options: QueryOptions) -> Result<ColorScheme> {
color_palette(options).map(|p| p.color_scheme())
match cli_theme::cli_theme().map(|t| t.preference) {
Some(CliThemePreference::Dark) => Ok(ColorScheme::Dark),
Some(CliThemePreference::Light) => Ok(ColorScheme::Light),
_ => color_palette(options).map(|p| p.color_scheme()),
}
}

/// Queries the terminal for it's color scheme (foreground and background color).
Expand Down

0 comments on commit b4dba96

Please sign in to comment.