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 list_selected_fg: Color,
31 pub helpers_colors: Color,
33 pub status_message: Color,
34 pub popup_bg: Color,
36 pub popup_text: Color,
37 pub icon_rust: Color,
39 pub icon_maven: Color,
40 pub icon_flutter: Color,
41 pub icon_go: Color,
42 pub icon_python: Color,
43 pub icon_mise: Color,
44 pub icon_worktree: Color,
45 pub icon_worktree_lock: Color,
46 pub icon_gitmodules: Color,
47 pub icon_git: Color,
48 pub icon_folder: Color,
49 pub icon_file: Color,
50}
51
52impl Default for Theme {
53 fn default() -> Self {
54 Self::default_theme()
55 }
56}
57
58struct Palette {
73 accent1: Color,
74 accent2: Color,
75 warm: Color,
76 cool: Color,
77 green: Color,
78 yellow: Color,
79 purple: Color,
80 overlay: Color,
81 subtext: Color,
82 surface: Color,
83 text: Color,
84 base: Color,
85}
86
87impl Theme {
88 fn from_palette(name: &str, background: Option<Color>, p: Palette) -> Self {
90 Self {
91 name: name.to_string(),
92 background,
93 title_try: p.accent1,
94 title_rs: p.accent2,
95 search_title: p.warm,
96 search_border: p.overlay,
97 folder_title: p.green,
98 folder_border: p.overlay,
99 disk_title: p.yellow,
100 disk_border: p.overlay,
101 preview_title: p.accent1,
102 preview_border: p.overlay,
103 legends_title: p.purple,
104 legends_border: p.overlay,
105 list_date: p.subtext,
106 list_highlight_bg: p.surface,
107 list_highlight_fg: p.text,
108 list_selected_fg: p.text,
109 helpers_colors: p.overlay,
110 status_message: p.yellow,
111 popup_bg: p.base,
112 popup_text: p.accent2,
113 icon_rust: p.warm,
114 icon_maven: p.accent2,
115 icon_flutter: p.accent1,
116 icon_go: p.cool,
117 icon_python: p.yellow,
118 icon_mise: p.warm,
119 icon_worktree: p.green,
120 icon_worktree_lock: p.subtext,
121 icon_gitmodules: p.purple,
122 icon_git: p.accent2,
123 icon_folder: p.yellow,
124 icon_file: p.subtext,
125 }
126 }
127
128 pub fn default_theme() -> Self {
129 Self {
130 icon_rust: Color::Rgb(230, 100, 50),
132 icon_maven: Color::Rgb(255, 150, 50),
133 icon_flutter: Color::Rgb(2, 123, 222),
134 icon_go: Color::Rgb(0, 173, 216),
135 icon_python: Color::Yellow,
136 icon_mise: Color::Rgb(250, 179, 135),
137 icon_worktree: Color::Rgb(100, 180, 100),
138 icon_worktree_lock: Color::White,
139 icon_gitmodules: Color::Rgb(180, 130, 200),
140 icon_git: Color::Rgb(240, 80, 50),
141 icon_folder: Color::Rgb(249, 226, 175),
142 icon_file: Color::Rgb(166, 173, 200),
143 ..Self::from_palette(
144 "Default",
145 None,
146 Palette {
147 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), },
160 )
161 }
162 }
163
164 pub fn catppuccin_mocha() -> Self {
165 Self::from_palette(
166 "Catppuccin Mocha",
167 Some(Color::Rgb(30, 30, 46)),
168 Palette {
169 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), },
182 )
183 }
184
185 pub fn catppuccin_macchiato() -> Self {
186 Self {
187 title_rs: Color::Rgb(238, 153, 160), ..Self::from_palette(
189 "Catppuccin Macchiato",
190 Some(Color::Rgb(36, 39, 58)),
191 Palette {
192 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), },
205 )
206 }
207 }
208
209 pub fn dracula() -> Self {
210 let cyan = Color::Rgb(139, 233, 253);
211 Self {
212 preview_title: cyan,
213 list_date: cyan,
214 popup_text: Color::Rgb(255, 85, 85), icon_flutter: cyan,
216 icon_go: cyan,
217 icon_file: cyan,
218 icon_maven: Color::Rgb(255, 85, 85), icon_worktree_lock: Color::Rgb(248, 248, 242), ..Self::from_palette(
221 "Dracula",
222 Some(Color::Rgb(40, 42, 54)),
223 Palette {
224 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), },
237 )
238 }
239 }
240
241 pub fn jetbrains_darcula() -> Self {
242 Self {
243 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(
249 "JetBrains Darcula",
250 Some(Color::Rgb(43, 43, 43)),
251 Palette {
252 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), },
265 )
266 }
267 }
268
269 pub fn gruvbox_dark() -> Self {
270 Self {
271 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(
280 "Gruvbox Dark",
281 Some(Color::Rgb(40, 40, 40)),
282 Palette {
283 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), },
296 )
297 }
298 }
299
300 pub fn nord() -> Self {
301 Self {
302 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(
307 "Nord",
308 Some(Color::Rgb(46, 52, 64)),
309 Palette {
310 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), },
323 )
324 }
325 }
326
327 pub fn tokyo_night() -> Self {
328 let cyan = Color::Rgb(125, 207, 255);
329 Self {
330 search_title: Color::Rgb(158, 206, 106), disk_title: Color::Rgb(255, 158, 100), preview_title: cyan,
333 icon_flutter: cyan,
334 icon_go: cyan,
335 icon_worktree: Color::Rgb(158, 206, 106), ..Self::from_palette(
337 "Tokyo Night",
338 Some(Color::Rgb(26, 27, 38)),
339 Palette {
340 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), },
353 )
354 }
355 }
356
357 pub fn one_dark_pro() -> Self {
358 let cyan = Color::Rgb(86, 182, 194);
359 Self {
360 preview_title: cyan,
361 icon_flutter: cyan,
362 icon_go: cyan,
363 ..Self::from_palette(
364 "One Dark Pro",
365 Some(Color::Rgb(40, 44, 52)),
366 Palette {
367 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), },
380 )
381 }
382 }
383
384 pub fn everforest() -> Self {
385 Self::from_palette(
386 "Everforest",
387 Some(Color::Rgb(45, 51, 48)),
388 Palette {
389 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), },
402 )
403 }
404
405 pub fn synthwave_84() -> Self {
406 Self {
407 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(
413 "SynthWave '84",
414 Some(Color::Rgb(38, 29, 53)),
415 Palette {
416 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), },
429 )
430 }
431 }
432
433 pub fn oled_true_black() -> Self {
434 Self {
435 helpers_colors: Color::Rgb(100, 100, 100), icon_rust: Color::Rgb(255, 120, 50), icon_mise: Color::Rgb(255, 180, 0), ..Self::from_palette(
439 "OLED True Black",
440 Some(Color::Rgb(0, 0, 0)),
441 Palette {
442 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), },
455 )
456 }
457 }
458
459 pub fn silver_gray() -> Self {
460 Self {
461 preview_title: Color::Rgb(176, 196, 222), icon_rust: Color::Rgb(210, 105, 30), icon_go: Color::Rgb(176, 196, 222), ..Self::from_palette(
465 "Silver Gray",
466 Some(Color::Rgb(47, 47, 47)),
467 Palette {
468 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), },
481 )
482 }
483 }
484
485 pub fn black_and_white() -> Self {
486 Self {
487 icon_mise: Color::Gray,
488 icon_gitmodules: Color::Gray,
489 popup_text: Color::White,
490 list_highlight_bg: Color::White,
491 list_highlight_fg: Color::Gray,
492 list_selected_fg: Color::Black,
493 ..Self::from_palette(
494 "Black & White",
495 Some(Color::Black),
496 Palette {
497 accent1: Color::White,
498 accent2: Color::White,
499 warm: Color::White,
500 cool: Color::White,
501 green: Color::White,
502 yellow: Color::White,
503 purple: Color::White,
504 overlay: Color::Gray,
505 subtext: Color::Gray,
506 surface: Color::White,
507 text: Color::White,
508 base: Color::Black,
509 },
510 )
511 }
512 }
513
514 pub fn matrix() -> Self {
515 let bright = Color::Rgb(0, 255, 65);
516 let dark = Color::Rgb(0, 100, 30);
517 let muted = Color::Rgb(0, 150, 40);
518 let darker = Color::Rgb(0, 200, 50);
519 Self {
520 helpers_colors: Color::Rgb(0, 150, 40), popup_text: Color::Rgb(0, 255, 65), icon_maven: Color::Rgb(0, 220, 55),
523 icon_flutter: Color::Rgb(0, 200, 50), icon_go: Color::Rgb(0, 180, 45),
525 icon_mise: Color::Rgb(0, 150, 40), icon_worktree: darker,
527 icon_worktree_lock: Color::Rgb(0, 120, 35),
528 icon_gitmodules: Color::Rgb(0, 180, 45),
529 icon_folder: Color::Rgb(0, 220, 55),
530 ..Self::from_palette(
531 "Matrix",
532 Some(Color::Rgb(0, 10, 0)),
533 Palette {
534 accent1: bright,
535 accent2: darker,
536 warm: bright,
537 cool: Color::Rgb(0, 180, 45),
538 green: bright,
539 yellow: bright,
540 purple: darker,
541 overlay: dark,
542 subtext: muted,
543 surface: Color::Rgb(0, 80, 25),
544 text: bright,
545 base: Color::Rgb(0, 10, 0),
546 },
547 )
548 }
549 }
550
551 pub fn tron() -> Self {
552 let cyan = Color::Rgb(0, 255, 255);
553 let orange = Color::Rgb(255, 150, 0);
554 let dk_cyan = Color::Rgb(0, 150, 180);
555 Self {
556 search_title: cyan,
557 folder_title: cyan,
558 legends_title: Color::Rgb(0, 200, 220),
559 popup_text: cyan,
560 icon_maven: Color::Rgb(255, 100, 0),
561 icon_go: Color::Rgb(0, 220, 230),
562 icon_python: Color::Rgb(255, 200, 0),
563 icon_worktree: cyan,
564 icon_worktree_lock: dk_cyan,
565 icon_gitmodules: Color::Rgb(0, 200, 220),
566 icon_folder: cyan,
567 ..Self::from_palette(
568 "Tron",
569 Some(Color::Rgb(0, 10, 15)),
570 Palette {
571 accent1: cyan,
572 accent2: orange,
573 warm: orange,
574 cool: Color::Rgb(0, 220, 230),
575 green: cyan,
576 yellow: orange,
577 purple: Color::Rgb(0, 200, 220),
578 overlay: dk_cyan,
579 subtext: Color::Rgb(0, 180, 200),
580 surface: Color::Rgb(0, 80, 100),
581 text: cyan,
582 base: Color::Rgb(0, 10, 15),
583 },
584 )
585 }
586 }
587
588 pub fn all() -> Vec<Theme> {
589 vec![
590 Theme::default_theme(),
591 Theme::catppuccin_mocha(),
592 Theme::catppuccin_macchiato(),
593 Theme::dracula(),
594 Theme::jetbrains_darcula(),
595 Theme::gruvbox_dark(),
596 Theme::nord(),
597 Theme::tokyo_night(),
598 Theme::one_dark_pro(),
599 Theme::everforest(),
600 Theme::synthwave_84(),
601 Theme::oled_true_black(),
602 Theme::silver_gray(),
603 Theme::black_and_white(),
604 Theme::matrix(),
605 Theme::tron(),
606 ]
607 }
608}