Skip to content

Commit

Permalink
Replace "light mode" bool with a dedicated enum
Browse files Browse the repository at this point in the history
  • Loading branch information
bash committed Sep 6, 2024
1 parent f00a80b commit b33459b
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 109 deletions.
3 changes: 2 additions & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use syntect::highlighting::Theme as SyntaxTheme;
use syntect::parsing::SyntaxSet;

use crate::ansi::{ANSI_SGR_BOLD, ANSI_SGR_RESET, ANSI_SGR_UNDERLINE};
use crate::color::ColorMode;
use crate::config::delta_unreachable;
use crate::env::DeltaEnv;
use crate::git_config::GitConfig;
Expand Down Expand Up @@ -1180,7 +1181,7 @@ pub struct ComputedValues {
pub background_color_extends_to_terminal_width: bool,
pub decorations_width: Width,
pub inspect_raw_lines: InspectRawLines,
pub is_light_mode: bool,
pub color_mode: ColorMode,
pub paging_mode: PagingMode,
pub syntax_set: SyntaxSet,
pub syntax_theme: Option<SyntaxTheme>,
Expand Down
60 changes: 36 additions & 24 deletions src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use syntect::highlighting::Color as SyntectColor;
use crate::fatal;
use crate::git_config::GitConfig;
use crate::utils;
use ColorMode::*;

pub fn parse_color(s: &str, true_color: bool, git_config: Option<&GitConfig>) -> Option<Color> {
if s == "normal" {
Expand Down Expand Up @@ -105,39 +106,50 @@ fn ansi_16_color_number_to_name(n: u8) -> Option<&'static str> {
None
}

pub fn get_minus_background_color_default(is_light_mode: bool, is_true_color: bool) -> Color {
match (is_light_mode, is_true_color) {
(true, true) => LIGHT_THEME_MINUS_COLOR,
(true, false) => LIGHT_THEME_MINUS_COLOR_256,
(false, true) => DARK_THEME_MINUS_COLOR,
(false, false) => DARK_THEME_MINUS_COLOR_256,
/// The color mode determines some default color choices
/// such as the diff background color or the palette used for blame.
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq)]
pub enum ColorMode {
#[default]
/// Dark background with light text.
Dark,
/// Light background with dark text.
Light,
}

pub fn get_minus_background_color_default(mode: ColorMode, is_true_color: bool) -> Color {
match (mode, is_true_color) {
(Light, true) => LIGHT_THEME_MINUS_COLOR,
(Light, false) => LIGHT_THEME_MINUS_COLOR_256,
(Dark, true) => DARK_THEME_MINUS_COLOR,
(Dark, false) => DARK_THEME_MINUS_COLOR_256,
}
}

pub fn get_minus_emph_background_color_default(is_light_mode: bool, is_true_color: bool) -> Color {
match (is_light_mode, is_true_color) {
(true, true) => LIGHT_THEME_MINUS_EMPH_COLOR,
(true, false) => LIGHT_THEME_MINUS_EMPH_COLOR_256,
(false, true) => DARK_THEME_MINUS_EMPH_COLOR,
(false, false) => DARK_THEME_MINUS_EMPH_COLOR_256,
pub fn get_minus_emph_background_color_default(mode: ColorMode, is_true_color: bool) -> Color {
match (mode, is_true_color) {
(Light, true) => LIGHT_THEME_MINUS_EMPH_COLOR,
(Light, false) => LIGHT_THEME_MINUS_EMPH_COLOR_256,
(Dark, true) => DARK_THEME_MINUS_EMPH_COLOR,
(Dark, false) => DARK_THEME_MINUS_EMPH_COLOR_256,
}
}

pub fn get_plus_background_color_default(is_light_mode: bool, is_true_color: bool) -> Color {
match (is_light_mode, is_true_color) {
(true, true) => LIGHT_THEME_PLUS_COLOR,
(true, false) => LIGHT_THEME_PLUS_COLOR_256,
(false, true) => DARK_THEME_PLUS_COLOR,
(false, false) => DARK_THEME_PLUS_COLOR_256,
pub fn get_plus_background_color_default(mode: ColorMode, is_true_color: bool) -> Color {
match (mode, is_true_color) {
(Light, true) => LIGHT_THEME_PLUS_COLOR,
(Light, false) => LIGHT_THEME_PLUS_COLOR_256,
(Dark, true) => DARK_THEME_PLUS_COLOR,
(Dark, false) => DARK_THEME_PLUS_COLOR_256,
}
}

pub fn get_plus_emph_background_color_default(is_light_mode: bool, is_true_color: bool) -> Color {
match (is_light_mode, is_true_color) {
(true, true) => LIGHT_THEME_PLUS_EMPH_COLOR,
(true, false) => LIGHT_THEME_PLUS_EMPH_COLOR_256,
(false, true) => DARK_THEME_PLUS_EMPH_COLOR,
(false, false) => DARK_THEME_PLUS_EMPH_COLOR_256,
pub fn get_plus_emph_background_color_default(mode: ColorMode, is_true_color: bool) -> Color {
match (mode, is_true_color) {
(Light, true) => LIGHT_THEME_PLUS_EMPH_COLOR,
(Light, false) => LIGHT_THEME_PLUS_EMPH_COLOR_256,
(Dark, true) => DARK_THEME_PLUS_EMPH_COLOR,
(Dark, false) => DARK_THEME_PLUS_EMPH_COLOR_256,
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use syntect::parsing::SyntaxSet;

use crate::ansi;
use crate::cli;
use crate::color;
use crate::color::{self, ColorMode};
use crate::delta::State;
use crate::fatal;
use crate::features::navigate;
Expand Down Expand Up @@ -214,7 +214,7 @@ impl From<cli::Opt> for Config {
));
});

let blame_palette = make_blame_palette(opt.blame_palette, opt.computed.is_light_mode);
let blame_palette = make_blame_palette(opt.blame_palette, opt.computed.color_mode);

if blame_palette.is_empty() {
fatal("Option 'blame-palette' must not be empty.")
Expand Down Expand Up @@ -437,17 +437,17 @@ impl From<cli::Opt> for Config {
}
}

fn make_blame_palette(blame_palette: Option<String>, is_light_mode: bool) -> Vec<String> {
match (blame_palette, is_light_mode) {
fn make_blame_palette(blame_palette: Option<String>, mode: ColorMode) -> Vec<String> {
match (blame_palette, mode) {
(Some(string), _) => string
.split_whitespace()
.map(|s| s.to_owned())
.collect::<Vec<String>>(),
(None, true) => color::LIGHT_THEME_BLAME_PALETTE
(None, ColorMode::Light) => color::LIGHT_THEME_BLAME_PALETTE
.iter()
.map(|s| s.to_string())
.collect::<Vec<String>>(),
(None, false) => color::DARK_THEME_BLAME_PALETTE
(None, ColorMode::Dark) => color::DARK_THEME_BLAME_PALETTE
.iter()
.map(|s| s.to_string())
.collect::<Vec<String>>(),
Expand Down
20 changes: 11 additions & 9 deletions src/features/line_numbers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::cmp::max;
use lazy_static::lazy_static;
use regex::Regex;

use crate::color::ColorMode::*;
use crate::config;
use crate::delta::State;
use crate::features::hyperlinks;
Expand Down Expand Up @@ -38,26 +39,27 @@ pub fn make_feature() -> Vec<(String, OptionValueFunction)> {
"line-numbers-minus-style",
String,
None,
opt => if opt.computed.is_light_mode {
"red".to_string()
} else {
"88".to_string()
opt => match opt.computed.color_mode {
Light => "red",
Dark => "88",
}
),
(
"line-numbers-zero-style",
String,
None,
opt => if opt.computed.is_light_mode {"#dddddd"} else {"#444444"}
opt => match opt.computed.color_mode {
Light => "#dddddd",
Dark => "#444444",
}
),
(
"line-numbers-plus-style",
String,
None,
opt => if opt.computed.is_light_mode {
"green".to_string()
} else {
"28".to_string()
opt => match opt.computed.color_mode {
Light => "green",
Dark => "28",
}
)
])
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ fn run_app() -> std::io::Result<i32> {
Some(subcommands::show_themes::show_themes(
opt.dark,
opt.light,
opt.computed.is_light_mode,
opt.computed.color_mode,
))
} else if opt.show_colors {
Some(subcommands::show_colors::show_colors())
Expand Down
86 changes: 43 additions & 43 deletions src/options/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,23 @@ use std::io::{stdout, IsTerminal};
use bat;
use bat::assets::HighlightingAssets;
#[cfg(not(test))]
use terminal_colorsaurus::{color_scheme, ColorScheme, QueryOptions};
use terminal_colorsaurus::{color_scheme, QueryOptions};

use crate::cli::{self, DetectDarkLight};
use crate::color::{ColorMode, ColorMode::*};

#[allow(non_snake_case)]
pub fn set__is_light_mode__syntax_theme__syntax_set(
opt: &mut cli::Opt,
assets: HighlightingAssets,
) {
let syntax_theme_name_from_bat_theme = &opt.env.bat_theme;
let (is_light_mode, syntax_theme_name) = get_is_light_mode_and_syntax_theme_name(
let (color_mode, syntax_theme_name) = get_is_light_mode_and_syntax_theme_name(
opt.syntax_theme.as_ref(),
syntax_theme_name_from_bat_theme.as_ref(),
get_is_light(opt),
get_color_mode(opt),
);
opt.computed.is_light_mode = is_light_mode;
opt.computed.color_mode = color_mode;

opt.computed.syntax_theme = if is_no_syntax_highlighting_syntax_theme_name(&syntax_theme_name) {
None
Expand All @@ -43,6 +44,14 @@ pub fn is_light_syntax_theme(theme: &str) -> bool {
LIGHT_SYNTAX_THEMES.contains(&theme) || theme.to_lowercase().contains("light")
}

pub fn color_mode_from_syntax_theme(theme: &str) -> ColorMode {
if is_light_syntax_theme(theme) {
ColorMode::Light
} else {
ColorMode::Dark
}
}

const LIGHT_SYNTAX_THEMES: [&str; 7] = [
"Catppuccin Latte",
"GitHub",
Expand Down Expand Up @@ -91,31 +100,31 @@ fn is_no_syntax_highlighting_syntax_theme_name(theme_name: &str) -> bool {
fn get_is_light_mode_and_syntax_theme_name(
theme_arg: Option<&String>,
bat_theme_env_var: Option<&String>,
light_mode: Option<bool>,
) -> (bool, String) {
mode: Option<ColorMode>,
) -> (ColorMode, String) {
let theme_arg = theme_arg.or(bat_theme_env_var);
match (theme_arg, light_mode) {
(Some(theme_name), None) => (is_light_syntax_theme(theme_name), theme_name.to_string()),
(Some(theme_name), Some(is_light_mode)) => (is_light_mode, theme_name.to_string()),
(None, None | Some(false)) => (false, DEFAULT_DARK_SYNTAX_THEME.to_string()),
(None, Some(true)) => (true, DEFAULT_LIGHT_SYNTAX_THEME.to_string()),
match (theme_arg, mode) {
(Some(theme), None) => (color_mode_from_syntax_theme(theme), theme.to_string()),
(Some(theme), Some(mode)) => (mode, theme.to_string()),
(None, None | Some(Dark)) => (Dark, DEFAULT_DARK_SYNTAX_THEME.to_string()),
(None, Some(Light)) => (Light, DEFAULT_LIGHT_SYNTAX_THEME.to_string()),
}
}

fn get_is_light(opt: &cli::Opt) -> Option<bool> {
fn get_color_mode(opt: &cli::Opt) -> Option<ColorMode> {
if opt.light {
Some(true)
Some(Light)
} else if opt.dark {
Some(false)
Some(Dark)
} else if should_detect_color_mode(opt) {
detect_color_mode()
} else {
should_detect_dark_light(opt)
.then(detect_light_mode)
.flatten()
None
}
}

/// See [`cli::Opt::detect_dark_light`] for a detailed explanation.
fn should_detect_dark_light(opt: &cli::Opt) -> bool {
fn should_detect_color_mode(opt: &cli::Opt) -> bool {
match opt.detect_dark_light {
DetectDarkLight::Auto => opt.color_only || stdout().is_terminal(),
DetectDarkLight::Always => true,
Expand All @@ -124,14 +133,23 @@ fn should_detect_dark_light(opt: &cli::Opt) -> bool {
}

#[cfg(not(test))]
fn detect_light_mode() -> Option<bool> {
fn detect_color_mode() -> Option<ColorMode> {
color_scheme(QueryOptions::default())
.ok()
.map(|color_scheme| color_scheme == ColorScheme::Light)
.map(ColorMode::from)
}

impl From<terminal_colorsaurus::ColorScheme> for ColorMode {
fn from(value: terminal_colorsaurus::ColorScheme) -> Self {
match value {
terminal_colorsaurus::ColorScheme::Dark => ColorMode::Dark,
terminal_colorsaurus::ColorScheme::Light => ColorMode::Light,
}
}
}

#[cfg(test)]
fn detect_light_mode() -> Option<bool> {
fn detect_color_mode() -> Option<ColorMode> {
None
}

Expand All @@ -144,12 +162,6 @@ mod tests {
// TODO: Test influence of BAT_THEME env var. E.g. see utils::process::tests::FakeParentArgs.
#[test]
fn test_syntax_theme_selection() {
use Mode::*;
#[derive(PartialEq)]
enum Mode {
Light,
Dark,
}
for (
syntax_theme,
mode, // (--light, --dark)
Expand Down Expand Up @@ -210,31 +222,19 @@ mod tests {
}
assert_eq!(
config.minus_style.ansi_term_style.background.unwrap(),
color::get_minus_background_color_default(
expected_mode == Mode::Light,
is_true_color
)
color::get_minus_background_color_default(expected_mode, is_true_color)
);
assert_eq!(
config.minus_emph_style.ansi_term_style.background.unwrap(),
color::get_minus_emph_background_color_default(
expected_mode == Mode::Light,
is_true_color
)
color::get_minus_emph_background_color_default(expected_mode, is_true_color)
);
assert_eq!(
config.plus_style.ansi_term_style.background.unwrap(),
color::get_plus_background_color_default(
expected_mode == Mode::Light,
is_true_color
)
color::get_plus_background_color_default(expected_mode, is_true_color)
);
assert_eq!(
config.plus_emph_style.ansi_term_style.background.unwrap(),
color::get_plus_emph_background_color_default(
expected_mode == Mode::Light,
is_true_color
)
color::get_plus_emph_background_color_default(expected_mode, is_true_color)
);
}
}
Expand Down
Loading

0 comments on commit b33459b

Please sign in to comment.