1use ratatui::style::Color;
2
3#[derive(Debug, Clone, Copy, PartialEq)]
4pub enum ThemeMode {
5 Dark,
6 Light,
7 Auto,
8}
9
10#[derive(Debug, Clone)]
11pub struct Theme {
12 pub selection_bg: Color,
14 pub file_header_bg: Color,
15 pub added_line_bg: Color,
16 pub removed_line_bg: Color,
17 pub added_emphasis_bg: Color, pub removed_emphasis_bg: Color, pub file_header_fg: Color,
20 pub context_fg: Color,
21 pub context_bg: Color,
22
23 pub gutter_fg: Color,
25
26 pub help_text_fg: Color,
28 pub help_section_fg: Color, pub help_key_fg: Color, pub help_dismiss_fg: Color, pub help_overlay_bg: Color, pub tree_highlight_fg: Color,
35 pub tree_highlight_bg: Color,
36 pub tree_group_fg: Color,
37
38 pub search_match_fg: Color,
40 pub search_match_bg: Color,
41
42 pub syntect_theme: &'static str,
44}
45
46impl Theme {
47 pub fn dark() -> Self {
48 Self {
49 selection_bg: Color::Rgb(40, 40, 60),
50 file_header_bg: Color::Rgb(30, 30, 40),
51 added_line_bg: Color::Rgb(0, 40, 0),
52 removed_line_bg: Color::Rgb(40, 0, 0),
53 added_emphasis_bg: Color::Rgb(0, 80, 0),
54 removed_emphasis_bg: Color::Rgb(80, 0, 0),
55 file_header_fg: Color::White,
56 context_fg: Color::Reset,
57 context_bg: Color::Reset,
58 gutter_fg: Color::DarkGray,
59 help_text_fg: Color::White,
60 help_section_fg: Color::Cyan,
61 help_key_fg: Color::Yellow,
62 help_dismiss_fg: Color::DarkGray,
63 help_overlay_bg: Color::Black,
64 tree_highlight_fg: Color::Black,
65 tree_highlight_bg: Color::Cyan,
66 tree_group_fg: Color::Cyan,
67 search_match_fg: Color::Black,
68 search_match_bg: Color::Yellow,
69 syntect_theme: "base16-ocean.dark",
70 }
71 }
72
73 pub fn light() -> Self {
74 Self {
75 selection_bg: Color::Rgb(210, 210, 230),
76 file_header_bg: Color::Rgb(220, 220, 235),
77 added_line_bg: Color::Rgb(210, 255, 210),
78 removed_line_bg: Color::Rgb(255, 210, 210),
79 added_emphasis_bg: Color::Rgb(170, 240, 170),
80 removed_emphasis_bg: Color::Rgb(240, 170, 170),
81 file_header_fg: Color::Black,
82 context_fg: Color::Reset,
83 context_bg: Color::Reset,
84 gutter_fg: Color::Gray,
85 help_text_fg: Color::Black,
86 help_section_fg: Color::Blue,
87 help_key_fg: Color::Red,
88 help_dismiss_fg: Color::Gray,
89 help_overlay_bg: Color::White,
90 tree_highlight_fg: Color::White,
91 tree_highlight_bg: Color::Blue,
92 tree_group_fg: Color::Blue,
93 search_match_fg: Color::Black,
94 search_match_bg: Color::Yellow,
95 syntect_theme: "base16-ocean.light",
96 }
97 }
98
99 pub fn from_mode(mode: ThemeMode) -> Self {
100 match mode {
101 ThemeMode::Dark => Self::dark(),
102 ThemeMode::Light => Self::light(),
103 ThemeMode::Auto => {
104 if detect_light_background() {
105 Self::light()
106 } else {
107 Self::dark()
108 }
109 }
110 }
111 }
112}
113
114fn detect_light_background() -> bool {
117 use std::io::IsTerminal;
118
119 if !std::io::stdin().is_terminal() || !std::io::stdout().is_terminal() {
121 return false;
122 }
123 if std::env::var("CI").is_ok() || std::env::var("TERM").as_deref() == Ok("dumb") {
124 return false;
125 }
126
127 match terminal_light::luma() {
128 Ok(luma) => luma > 0.6,
129 Err(_) => false,
130 }
131}