1use ratatui::style::Color;
2
3#[derive(Clone)]
4pub struct Theme {
5 pub name: String,
6 pub background: Option<Color>,
8 pub title_try: Color,
10 pub title_rs: Color,
11 pub search_title: Color,
13 pub search_border: Color,
14 pub folder_title: Color,
16 pub folder_border: Color,
17 pub disk_title: Color,
19 pub disk_border: Color,
20 pub preview_title: Color,
22 pub preview_border: Color,
23 pub legends_title: Color,
25 pub legends_border: Color,
26 pub list_date: Color,
28 pub list_highlight_bg: Color,
29 pub list_highlight_fg: Color,
30 pub helpers_colors: Color,
32 pub status_message: Color,
33 pub popup_bg: Color,
35 pub popup_text: Color,
36 pub icon_rust: Color,
38 pub icon_maven: Color,
39 pub icon_flutter: Color,
40 pub icon_go: Color,
41 pub icon_python: Color,
42 pub icon_mise: Color,
43 pub icon_worktree: Color,
44 pub icon_worktree_lock: Color,
45 pub icon_gitmodules: Color,
46 pub icon_git: Color,
47 pub icon_folder: Color,
48 pub icon_file: Color,
49}
50
51impl Default for Theme {
52 fn default() -> Self {
53 Self::default_theme()
54 }
55}
56
57struct Palette {
72 accent1: Color,
73 accent2: Color,
74 warm: Color,
75 cool: Color,
76 green: Color,
77 yellow: Color,
78 purple: Color,
79 overlay: Color,
80 subtext: Color,
81 surface: Color,
82 text: Color,
83 base: Color,
84}
85
86impl Theme {
87 fn from_palette(name: &str, background: Option<Color>, p: Palette) -> Self {
89 Self {
90 name: name.to_string(),
91 background,
92 title_try: p.accent1,
93 title_rs: p.accent2,
94 search_title: p.warm,
95 search_border: p.overlay,
96 folder_title: p.green,
97 folder_border: p.overlay,
98 disk_title: p.yellow,
99 disk_border: p.overlay,
100 preview_title: p.accent1,
101 preview_border: p.overlay,
102 legends_title: p.purple,
103 legends_border: p.overlay,
104 list_date: p.subtext,
105 list_highlight_bg: p.surface,
106 list_highlight_fg: p.text,
107 helpers_colors: p.overlay,
108 status_message: p.yellow,
109 popup_bg: p.base,
110 popup_text: p.accent2,
111 icon_rust: p.warm,
112 icon_maven: p.accent2,
113 icon_flutter: p.accent1,
114 icon_go: p.cool,
115 icon_python: p.yellow,
116 icon_mise: p.warm,
117 icon_worktree: p.green,
118 icon_worktree_lock: p.subtext,
119 icon_gitmodules: p.purple,
120 icon_git: p.accent2,
121 icon_folder: p.yellow,
122 icon_file: p.subtext,
123 }
124 }
125
126 pub fn default_theme() -> Self {
127 Self {
128 icon_rust: Color::Rgb(230, 100, 50),
130 icon_maven: Color::Rgb(255, 150, 50),
131 icon_flutter: Color::Rgb(2, 123, 222),
132 icon_go: Color::Rgb(0, 173, 216),
133 icon_python: Color::Yellow,
134 icon_mise: Color::Rgb(250, 179, 135),
135 icon_worktree: Color::Rgb(100, 180, 100),
136 icon_worktree_lock: Color::White,
137 icon_gitmodules: Color::Rgb(180, 130, 200),
138 icon_git: Color::Rgb(240, 80, 50),
139 icon_folder: Color::Rgb(249, 226, 175),
140 icon_file: Color::Rgb(166, 173, 200),
141 ..Self::from_palette(
142 "Default",
143 None,
144 Palette {
145 accent1: Color::Rgb(137, 180, 250), accent2: Color::Rgb(243, 139, 168), warm: Color::Rgb(250, 179, 135), cool: Color::Rgb(0, 173, 216), green: Color::Rgb(166, 227, 161), yellow: Color::Rgb(249, 226, 175), purple: Color::Rgb(203, 166, 247), overlay: Color::Rgb(147, 153, 178), subtext: Color::Rgb(166, 173, 200), surface: Color::Rgb(88, 91, 112), text: Color::Rgb(205, 214, 244), base: Color::Rgb(30, 30, 46), },
158 )
159 }
160 }
161
162 pub fn catppuccin_mocha() -> Self {
163 Self::from_palette(
164 "Catppuccin Mocha",
165 Some(Color::Rgb(30, 30, 46)),
166 Palette {
167 accent1: Color::Rgb(137, 180, 250), accent2: Color::Rgb(243, 139, 168), warm: Color::Rgb(250, 179, 135), cool: Color::Rgb(148, 226, 213), green: Color::Rgb(166, 227, 161), yellow: Color::Rgb(249, 226, 175), purple: Color::Rgb(203, 166, 247), overlay: Color::Rgb(147, 153, 178), subtext: Color::Rgb(166, 173, 200), surface: Color::Rgb(88, 91, 112), text: Color::Rgb(205, 214, 244), base: Color::Rgb(30, 30, 46), },
180 )
181 }
182
183 pub fn catppuccin_macchiato() -> Self {
184 Self {
185 title_rs: Color::Rgb(238, 153, 160), ..Self::from_palette(
187 "Catppuccin Macchiato",
188 Some(Color::Rgb(36, 39, 58)),
189 Palette {
190 accent1: Color::Rgb(138, 173, 244), accent2: Color::Rgb(237, 135, 150), warm: Color::Rgb(245, 169, 127), cool: Color::Rgb(139, 213, 202), green: Color::Rgb(166, 218, 149), yellow: Color::Rgb(238, 212, 159), purple: Color::Rgb(198, 160, 246), overlay: Color::Rgb(147, 154, 183), subtext: Color::Rgb(165, 173, 203), surface: Color::Rgb(91, 96, 120), text: Color::Rgb(202, 211, 245), base: Color::Rgb(36, 39, 58), },
203 )
204 }
205 }
206
207 pub fn dracula() -> Self {
208 let cyan = Color::Rgb(139, 233, 253);
209 Self {
210 preview_title: cyan,
211 list_date: cyan,
212 popup_text: Color::Rgb(255, 85, 85), icon_flutter: cyan,
214 icon_go: cyan,
215 icon_file: cyan,
216 icon_maven: Color::Rgb(255, 85, 85), icon_worktree_lock: Color::Rgb(248, 248, 242), ..Self::from_palette(
219 "Dracula",
220 Some(Color::Rgb(40, 42, 54)),
221 Palette {
222 accent1: Color::Rgb(189, 147, 249), accent2: Color::Rgb(255, 121, 198), warm: Color::Rgb(255, 184, 108), cool: Color::Rgb(139, 233, 253), green: Color::Rgb(80, 250, 123), yellow: Color::Rgb(241, 250, 140), purple: Color::Rgb(189, 147, 249), overlay: Color::Rgb(98, 114, 164), subtext: Color::Rgb(139, 233, 253), surface: Color::Rgb(68, 71, 90), text: Color::Rgb(248, 248, 242), base: Color::Rgb(40, 42, 54), },
235 )
236 }
237 }
238
239 pub fn jetbrains_darcula() -> Self {
240 Self {
241 search_title: Color::Rgb(106, 135, 89), disk_title: Color::Rgb(204, 120, 50), icon_maven: Color::Rgb(255, 198, 109), icon_worktree: Color::Rgb(106, 135, 89), icon_worktree_lock: Color::Rgb(187, 187, 187), ..Self::from_palette(
247 "JetBrains Darcula",
248 Some(Color::Rgb(43, 43, 43)),
249 Palette {
250 accent1: Color::Rgb(78, 124, 238), accent2: Color::Rgb(204, 120, 50), warm: Color::Rgb(204, 120, 50), cool: Color::Rgb(0, 173, 216), green: Color::Rgb(255, 198, 109), yellow: Color::Rgb(255, 198, 109), purple: Color::Rgb(152, 118, 170), overlay: Color::Rgb(128, 128, 128), subtext: Color::Rgb(128, 128, 128), surface: Color::Rgb(33, 66, 131), text: Color::Rgb(187, 187, 187), base: Color::Rgb(60, 63, 65), },
263 )
264 }
265 }
266
267 pub fn gruvbox_dark() -> Self {
268 Self {
269 title_rs: Color::Rgb(250, 189, 47), search_title: Color::Rgb(184, 187, 38), folder_title: Color::Rgb(250, 189, 47), disk_title: Color::Rgb(254, 128, 25), preview_title: Color::Rgb(131, 165, 152), status_message: Color::Rgb(215, 153, 33), icon_flutter: Color::Rgb(131, 165, 152), icon_worktree_lock: Color::Rgb(168, 153, 132), ..Self::from_palette(
278 "Gruvbox Dark",
279 Some(Color::Rgb(40, 40, 40)),
280 Palette {
281 accent1: Color::Rgb(251, 73, 52), accent2: Color::Rgb(251, 73, 52), warm: Color::Rgb(254, 128, 25), cool: Color::Rgb(131, 165, 152), green: Color::Rgb(184, 187, 38), yellow: Color::Rgb(250, 189, 47), purple: Color::Rgb(211, 134, 155), overlay: Color::Rgb(168, 153, 132), subtext: Color::Rgb(146, 131, 116), surface: Color::Rgb(80, 73, 69), text: Color::Rgb(235, 219, 178), base: Color::Rgb(40, 40, 40), },
294 )
295 }
296 }
297
298 pub fn nord() -> Self {
299 Self {
300 search_title: Color::Rgb(163, 190, 140), folder_title: Color::Rgb(235, 203, 139), disk_title: Color::Rgb(208, 135, 112), icon_worktree: Color::Rgb(163, 190, 140), ..Self::from_palette(
305 "Nord",
306 Some(Color::Rgb(46, 52, 64)),
307 Palette {
308 accent1: Color::Rgb(136, 192, 208), accent2: Color::Rgb(191, 97, 106), warm: Color::Rgb(208, 135, 112), cool: Color::Rgb(136, 192, 208), green: Color::Rgb(163, 190, 140), yellow: Color::Rgb(235, 203, 139), purple: Color::Rgb(180, 142, 173), overlay: Color::Rgb(76, 86, 106), subtext: Color::Rgb(216, 222, 233), surface: Color::Rgb(67, 76, 94), text: Color::Rgb(236, 239, 244), base: Color::Rgb(46, 52, 64), },
321 )
322 }
323 }
324
325 pub fn tokyo_night() -> Self {
326 let cyan = Color::Rgb(125, 207, 255);
327 Self {
328 search_title: Color::Rgb(158, 206, 106), disk_title: Color::Rgb(255, 158, 100), preview_title: cyan,
331 icon_flutter: cyan,
332 icon_go: cyan,
333 icon_worktree: Color::Rgb(158, 206, 106), ..Self::from_palette(
335 "Tokyo Night",
336 Some(Color::Rgb(26, 27, 38)),
337 Palette {
338 accent1: Color::Rgb(122, 162, 247), accent2: Color::Rgb(247, 118, 142), warm: Color::Rgb(255, 158, 100), cool: Color::Rgb(125, 207, 255), green: Color::Rgb(224, 175, 104), yellow: Color::Rgb(224, 175, 104), purple: Color::Rgb(187, 154, 247), overlay: Color::Rgb(86, 95, 137), subtext: Color::Rgb(169, 177, 214), surface: Color::Rgb(65, 72, 104), text: Color::Rgb(192, 202, 245), base: Color::Rgb(26, 27, 38), },
351 )
352 }
353 }
354
355 pub fn one_dark_pro() -> Self {
356 let cyan = Color::Rgb(86, 182, 194);
357 Self {
358 preview_title: cyan,
359 icon_flutter: cyan,
360 icon_go: cyan,
361 ..Self::from_palette(
362 "One Dark Pro",
363 Some(Color::Rgb(40, 44, 52)),
364 Palette {
365 accent1: Color::Rgb(97, 175, 239), accent2: Color::Rgb(224, 108, 117), warm: Color::Rgb(209, 154, 102), cool: Color::Rgb(86, 182, 194), green: Color::Rgb(152, 195, 121), yellow: Color::Rgb(229, 192, 123), purple: Color::Rgb(198, 120, 221), overlay: Color::Rgb(92, 99, 112), subtext: Color::Rgb(171, 178, 191), surface: Color::Rgb(62, 68, 81), text: Color::Rgb(220, 223, 228), base: Color::Rgb(40, 44, 52), },
378 )
379 }
380 }
381
382 pub fn everforest() -> Self {
383 Self::from_palette(
384 "Everforest",
385 Some(Color::Rgb(45, 51, 48)),
386 Palette {
387 accent1: Color::Rgb(127, 187, 179), accent2: Color::Rgb(230, 126, 128), warm: Color::Rgb(230, 152, 117), cool: Color::Rgb(127, 187, 179), green: Color::Rgb(167, 192, 128), yellow: Color::Rgb(219, 188, 127), purple: Color::Rgb(214, 153, 182), overlay: Color::Rgb(127, 132, 120), subtext: Color::Rgb(211, 198, 170), surface: Color::Rgb(80, 88, 77), text: Color::Rgb(211, 198, 170), base: Color::Rgb(45, 51, 48), },
400 )
401 }
402
403 pub fn synthwave_84() -> Self {
404 Self {
405 search_title: Color::Rgb(255, 203, 107), legends_title: Color::Rgb(254, 78, 174), popup_text: Color::Rgb(254, 78, 174), icon_rust: Color::Rgb(255, 140, 66), icon_gitmodules: Color::Rgb(254, 78, 174), ..Self::from_palette(
411 "SynthWave '84",
412 Some(Color::Rgb(38, 29, 53)),
413 Palette {
414 accent1: Color::Rgb(54, 244, 244), accent2: Color::Rgb(255, 126, 185), warm: Color::Rgb(255, 140, 66), cool: Color::Rgb(54, 244, 244), green: Color::Rgb(114, 241, 177), yellow: Color::Rgb(255, 203, 107), purple: Color::Rgb(254, 78, 174), overlay: Color::Rgb(129, 91, 164), subtext: Color::Rgb(187, 186, 201), surface: Color::Rgb(57, 43, 75), text: Color::Rgb(255, 255, 255), base: Color::Rgb(38, 29, 53), },
427 )
428 }
429 }
430
431 pub fn oled_true_black() -> Self {
432 Self {
433 helpers_colors: Color::Rgb(100, 100, 100), icon_rust: Color::Rgb(255, 120, 50), icon_mise: Color::Rgb(255, 180, 0), ..Self::from_palette(
437 "OLED True Black",
438 Some(Color::Rgb(0, 0, 0)),
439 Palette {
440 accent1: Color::Rgb(0, 200, 255), accent2: Color::Rgb(255, 80, 100), warm: Color::Rgb(255, 180, 0), cool: Color::Rgb(0, 200, 255), green: Color::Rgb(0, 230, 130), yellow: Color::Rgb(255, 220, 0), purple: Color::Rgb(200, 100, 255), overlay: Color::Rgb(60, 60, 60), subtext: Color::Rgb(180, 180, 180), surface: Color::Rgb(30, 30, 30), text: Color::Rgb(255, 255, 255), base: Color::Rgb(0, 0, 0), },
453 )
454 }
455 }
456
457 pub fn silver_gray() -> Self {
458 Self {
459 preview_title: Color::Rgb(176, 196, 222), icon_rust: Color::Rgb(210, 105, 30), icon_go: Color::Rgb(176, 196, 222), ..Self::from_palette(
463 "Silver Gray",
464 Some(Color::Rgb(47, 47, 47)),
465 Palette {
466 accent1: Color::Rgb(100, 149, 237), accent2: Color::Rgb(205, 92, 92), warm: Color::Rgb(218, 165, 32), cool: Color::Rgb(176, 196, 222), green: Color::Rgb(144, 238, 144), yellow: Color::Rgb(240, 230, 140), purple: Color::Rgb(186, 85, 211), overlay: Color::Rgb(128, 128, 128), subtext: Color::Rgb(192, 192, 192), surface: Color::Rgb(70, 70, 70), text: Color::Rgb(245, 245, 245), base: Color::Rgb(47, 47, 47), },
479 )
480 }
481 }
482
483 pub fn black_and_white() -> Self {
484 Self {
485 icon_mise: Color::Gray,
486 icon_gitmodules: Color::Gray,
487 ..Self::from_palette(
488 "Black & White",
489 Some(Color::Black),
490 Palette {
491 accent1: Color::White,
492 accent2: Color::White,
493 warm: Color::White,
494 cool: Color::White,
495 green: Color::White,
496 yellow: Color::White,
497 purple: Color::White,
498 overlay: Color::Gray,
499 subtext: Color::Gray,
500 surface: Color::White,
501 text: Color::Black,
502 base: Color::Black,
503 },
504 )
505 }
506 }
507
508 pub fn matrix() -> Self {
509 let bright = Color::Rgb(0, 255, 65);
510 let dark = Color::Rgb(0, 100, 30);
511 let muted = Color::Rgb(0, 150, 40);
512 let darker = Color::Rgb(0, 200, 50);
513 Self {
514 helpers_colors: Color::Rgb(0, 150, 40), popup_text: Color::Rgb(0, 255, 65), icon_maven: Color::Rgb(0, 220, 55),
517 icon_flutter: Color::Rgb(0, 200, 50), icon_go: Color::Rgb(0, 180, 45),
519 icon_mise: Color::Rgb(0, 150, 40), icon_worktree: darker,
521 icon_worktree_lock: Color::Rgb(0, 120, 35),
522 icon_gitmodules: Color::Rgb(0, 180, 45),
523 icon_folder: Color::Rgb(0, 220, 55),
524 ..Self::from_palette(
525 "Matrix",
526 Some(Color::Rgb(0, 10, 0)),
527 Palette {
528 accent1: bright,
529 accent2: darker,
530 warm: bright,
531 cool: Color::Rgb(0, 180, 45),
532 green: bright,
533 yellow: bright,
534 purple: darker,
535 overlay: dark,
536 subtext: muted,
537 surface: Color::Rgb(0, 80, 25),
538 text: bright,
539 base: Color::Rgb(0, 10, 0),
540 },
541 )
542 }
543 }
544
545 pub fn tron() -> Self {
546 let cyan = Color::Rgb(0, 255, 255);
547 let orange = Color::Rgb(255, 150, 0);
548 let dk_cyan = Color::Rgb(0, 150, 180);
549 Self {
550 search_title: cyan,
551 folder_title: cyan,
552 legends_title: Color::Rgb(0, 200, 220),
553 popup_text: cyan,
554 icon_maven: Color::Rgb(255, 100, 0),
555 icon_go: Color::Rgb(0, 220, 230),
556 icon_python: Color::Rgb(255, 200, 0),
557 icon_worktree: cyan,
558 icon_worktree_lock: dk_cyan,
559 icon_gitmodules: Color::Rgb(0, 200, 220),
560 icon_folder: cyan,
561 ..Self::from_palette(
562 "Tron",
563 Some(Color::Rgb(0, 10, 15)),
564 Palette {
565 accent1: cyan,
566 accent2: orange,
567 warm: orange,
568 cool: Color::Rgb(0, 220, 230),
569 green: cyan,
570 yellow: orange,
571 purple: Color::Rgb(0, 200, 220),
572 overlay: dk_cyan,
573 subtext: Color::Rgb(0, 180, 200),
574 surface: Color::Rgb(0, 80, 100),
575 text: cyan,
576 base: Color::Rgb(0, 10, 15),
577 },
578 )
579 }
580 }
581
582 pub fn all() -> Vec<Theme> {
583 vec![
584 Theme::default_theme(),
585 Theme::catppuccin_mocha(),
586 Theme::catppuccin_macchiato(),
587 Theme::dracula(),
588 Theme::jetbrains_darcula(),
589 Theme::gruvbox_dark(),
590 Theme::nord(),
591 Theme::tokyo_night(),
592 Theme::one_dark_pro(),
593 Theme::everforest(),
594 Theme::synthwave_84(),
595 Theme::oled_true_black(),
596 Theme::silver_gray(),
597 Theme::black_and_white(),
598 Theme::matrix(),
599 Theme::tron(),
600 ]
601 }
602}