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 tree_highlight_fg: Color,
34 pub tree_highlight_bg: Color,
35 pub tree_group_fg: Color,
36
37 pub search_match_fg: Color,
39 pub search_match_bg: Color,
40
41 pub syntect_theme: &'static str,
43}
44
45impl Theme {
46 pub fn dark() -> Self {
47 Self {
48 selection_bg: Color::Rgb(40, 40, 60),
49 file_header_bg: Color::Rgb(30, 30, 40),
50 added_line_bg: Color::Rgb(0, 40, 0),
51 removed_line_bg: Color::Rgb(40, 0, 0),
52 added_emphasis_bg: Color::Rgb(0, 80, 0),
53 removed_emphasis_bg: Color::Rgb(80, 0, 0),
54 file_header_fg: Color::White,
55 context_fg: Color::Reset,
56 context_bg: Color::Reset,
57 gutter_fg: Color::DarkGray,
58 help_text_fg: Color::White,
59 help_section_fg: Color::Cyan,
60 help_key_fg: Color::Yellow,
61 help_dismiss_fg: Color::DarkGray,
62 tree_highlight_fg: Color::Black,
63 tree_highlight_bg: Color::Cyan,
64 tree_group_fg: Color::Cyan,
65 search_match_fg: Color::Black,
66 search_match_bg: Color::Yellow,
67 syntect_theme: "base16-ocean.dark",
68 }
69 }
70
71 pub fn light() -> Self {
72 Self {
73 selection_bg: Color::Rgb(210, 210, 230),
74 file_header_bg: Color::Rgb(220, 220, 235),
75 added_line_bg: Color::Rgb(210, 255, 210),
76 removed_line_bg: Color::Rgb(255, 210, 210),
77 added_emphasis_bg: Color::Rgb(170, 240, 170),
78 removed_emphasis_bg: Color::Rgb(240, 170, 170),
79 file_header_fg: Color::Black,
80 context_fg: Color::Reset,
81 context_bg: Color::Reset,
82 gutter_fg: Color::Gray,
83 help_text_fg: Color::Black,
84 help_section_fg: Color::Blue,
85 help_key_fg: Color::Rgb(160, 100, 0), help_dismiss_fg: Color::Gray,
87 tree_highlight_fg: Color::White,
88 tree_highlight_bg: Color::Blue,
89 tree_group_fg: Color::Blue,
90 search_match_fg: Color::Black,
91 search_match_bg: Color::Yellow,
92 syntect_theme: "base16-ocean.light",
93 }
94 }
95
96 pub fn from_mode(mode: ThemeMode) -> Self {
97 match mode {
98 ThemeMode::Dark => Self::dark(),
99 ThemeMode::Light => Self::light(),
100 ThemeMode::Auto => {
101 if detect_light_background() {
102 Self::light()
103 } else {
104 Self::dark()
105 }
106 }
107 }
108 }
109}
110
111fn detect_light_background() -> bool {
114 use std::io::IsTerminal;
115
116 if !std::io::stdin().is_terminal() || !std::io::stdout().is_terminal() {
118 return false;
119 }
120 if std::env::var("CI").is_ok() || std::env::var("TERM").as_deref() == Ok("dumb") {
121 return false;
122 }
123
124 match terminal_light::luma() {
125 Ok(luma) => luma > 0.6,
126 Err(_) => false,
127 }
128}