1use ratatui::style::{Color, Modifier, Style};
2
3use crate::highlight::Class;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub struct Palette {
10 pub removed: Style,
11 pub added: Style,
12 pub removed_emphasis: Style,
13 pub added_emphasis: Style,
14 pub moved_away: Style,
15 pub moved_here: Style,
16 pub removed_sign: Color,
17 pub added_sign: Color,
18 pub moved_sign: Color,
19 pub keyword: Color,
20 pub string: Color,
21 pub comment: Color,
22 pub number: Color,
23 pub search: Style,
24}
25
26const fn rgb(hex: u32) -> Color {
27 Color::Rgb((hex >> 16) as u8, (hex >> 8) as u8, hex as u8)
28}
29
30impl Palette {
31 pub const TRUE_COLOR: Palette = Palette {
34 removed: Style::new().bg(rgb(0x2d1b1f)),
35 added: Style::new().bg(rgb(0x1a2b20)),
36 removed_emphasis: Style::new().bg(rgb(0x5c2b33)),
37 added_emphasis: Style::new().bg(rgb(0x2b5237)),
38 moved_away: Style::new().bg(rgb(0x262033)),
39 moved_here: Style::new().bg(rgb(0x1b2a33)),
40 removed_sign: rgb(0xe0707a),
41 added_sign: rgb(0x7fc48a),
42 moved_sign: rgb(0x8fb3d9),
43 keyword: rgb(0xc2a8dc),
44 string: rgb(0xd2b98c),
45 comment: rgb(0x8c939e),
46 number: rgb(0xd9a07c),
47 search: Style::new().fg(Color::Black).bg(rgb(0xd7b84a)),
48 };
49
50 pub const COLOR_256: Palette = Palette {
54 removed: Style::new().add_modifier(Modifier::DIM),
55 added: Style::new(),
56 removed_emphasis: Style::new().bg(Color::Indexed(52)),
57 added_emphasis: Style::new().bg(Color::Indexed(22)),
58 moved_away: Style::new().add_modifier(Modifier::DIM),
59 moved_here: Style::new(),
60 removed_sign: Color::Indexed(167),
61 added_sign: Color::Indexed(114),
62 moved_sign: Color::Indexed(110),
63 keyword: Color::Indexed(140),
64 string: Color::Indexed(180),
65 comment: Color::Indexed(245),
66 number: Color::Indexed(173),
67 search: Style::new().fg(Color::Black).bg(Color::Indexed(179)),
68 };
69
70 pub fn detect() -> Palette {
72 match std::env::var("COLORTERM").as_deref() {
73 Ok("truecolor" | "24bit") => Palette::TRUE_COLOR,
74 _ => Palette::COLOR_256,
75 }
76 }
77
78 pub fn syntax(&self, class: Class) -> Option<Style> {
81 let fg = match class {
82 Class::Keyword => self.keyword,
83 Class::String => self.string,
84 Class::Number | Class::Constant => self.number,
85 Class::Comment => {
86 return Some(Style::new().fg(self.comment).add_modifier(Modifier::ITALIC));
87 }
88 Class::Type | Class::Function | Class::Attribute => return None,
89 };
90 Some(Style::new().fg(fg))
91 }
92}