summaryrefslogtreecommitdiff
path: root/src/widgets/luaeditor/theme.rs
blob: f0520f4f14269730d8b7f3d8c638bc1004248b6d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use mlua::{FromLua, IntoLua};
use ratatui::{style::Color, text::Span};
use tree_sitter_highlight::Highlight;

use crate::config::theme::style::Style;

pub(super) static HIGHLIGHT_NAMES: [&str; 29] = [
    "attribute",
    "boolean",
    "comment",
    "conditional",
    "constant",
    "constant.builtin",
    "constructor",
    "field",
    "function",
    "function.builtin",
    "function.call",
    "keyword",
    "keyword.function",
    "keyword.operator",
    "keyword.return",
    "label",
    "method",
    "method.call",
    "number",
    "operator",
    "parameter",
    "preproc",
    "punctuation.bracket",
    "punctuation.delimiter",
    "repeat",
    "string",
    "string.escape",
    "variable",
    "variable.builtin",
];

#[derive(Default, Debug, Clone)]
pub struct HighlightTheme {
    theme: [Style; 29],
}

impl HighlightTheme {
    pub const fn new() -> Self {
        Self {
            theme: [
                Style::new().fg(Color::White),  // attribute
                Style::new().fg(Color::White),  // boolean
                Style::new().fg(Color::White),  // comment
                Style::new().fg(Color::White),  // conditional
                Style::new().fg(Color::White),  // constant
                Style::new().fg(Color::White),  // constant.builtin
                Style::new().fg(Color::White),  // constructor
                Style::new().fg(Color::White),  // field
                Style::new().fg(Color::White),  // function
                Style::new().fg(Color::White),  // function.builtin
                Style::new().fg(Color::White),  // function.call
                Style::new().fg(Color::White),  // keyword
                Style::new().fg(Color::White),  // keyword.function
                Style::new().fg(Color::White),  // keyword.operator
                Style::new().fg(Color::White),  // keyword.return
                Style::new().fg(Color::White),  // label
                Style::new().fg(Color::White),  // method
                Style::new().fg(Color::White),  // method.call
                Style::new().fg(Color::White),  // number
                Style::new().fg(Color::White),  // operator
                Style::new().fg(Color::White),  // parameter
                Style::new().fg(Color::White),  // preproc
                Style::new().fg(Color::White),  // punctuation.bracket
                Style::new().fg(Color::White),  // punctuation.delimiter
                Style::new().fg(Color::White),  // repeat
                Style::new().fg(Color::White),  // string
                Style::new().fg(Color::White),  // string.escape
                Style::new().fg(Color::White),  // variable
                Style::new().fg(Color::White),  // variable.builtin
            ],
        }
    }

    pub fn highlight<'a>(&'a self, hl: Option<Highlight>, span: Span<'a>) -> Span<'a> {
        if let Some(hl) = hl {
            self.theme[hl.0].apply(span)
        } else {
            span
        }
    }
}

impl<'lua> IntoLua<'lua> for HighlightTheme {
    fn into_lua(
        self,
        lua: &'lua mlua::prelude::Lua,
    ) -> mlua::prelude::LuaResult<mlua::prelude::LuaValue<'lua>> {
        let table = lua.create_table()?;

        for (i, names) in HIGHLIGHT_NAMES.iter().enumerate() {
            table.set(names.replace('.', "_"), self.theme[i])?
        }

        table.into_lua(lua)
    }
}

impl<'lua> FromLua<'lua> for HighlightTheme {
    fn from_lua(
        value: mlua::prelude::LuaValue<'lua>,
        _lua: &'lua mlua::prelude::Lua,
    ) -> mlua::prelude::LuaResult<Self> {
        let mut theme = HighlightTheme::default();

        if value.is_table() {
            let table = value.as_table().unwrap();
            for (i, names) in HIGHLIGHT_NAMES.iter().enumerate() {
                if let Ok(style) = table.get(names.replace('.', "_")) {
                    theme.theme[i] = style;
                }
            }

            Ok(theme)
        } else {
            Err(mlua::prelude::LuaError::runtime(
                "failed to parse HighlightTheme",
            ))
        }
    }
}