Skip to main content

oak_lua/highlighter/
mod.rs

1/// 高亮类型的本地定义
2#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3pub enum HighlightKind {
4    /// 关键字
5    Keyword,
6    /// 字符串
7    String,
8    /// 数字
9    Number,
10    /// 注释
11    Comment,
12    /// 宏
13    Macro,
14    /// 标识符
15    Identifier,
16    /// 运算符
17    Operator,
18}
19
20/// 高亮器 trait
21pub trait Highlighter {
22    /// 对给定的文本进行高亮处理
23    fn highlight(&self, text: &str) -> Vec<(usize, usize, HighlightKind)>;
24}
25
26/// Lua 语法高亮器
27pub struct LuaHighlighter;
28
29impl LuaHighlighter {
30    pub fn new() -> Self {
31        Self
32    }
33}
34
35impl Highlighter for LuaHighlighter {
36    fn highlight(&self, text: &str) -> Vec<(usize, usize, HighlightKind)> {
37        let mut highlights = Vec::new();
38
39        // 简单的正则表达式或基于词法分析的高亮实现
40        // 这里我们可以复用 LuaLexer 来获取 Token
41        use crate::{kind::LuaSyntaxKind, lexer::LuaLexer};
42        use oak_core::{LexOutput, Lexer, LexerCache, SourceText, Token};
43
44        struct SimpleCache {
45            tokens: Vec<Token<LuaSyntaxKind>>,
46        }
47
48        impl LexerCache<crate::language::LuaLanguage> for SimpleCache {
49            fn set_lex_output(&mut self, output: LexOutput<crate::language::LuaLanguage>) {
50                if let Ok(tokens) = output.result {
51                    self.tokens = tokens.to_vec();
52                }
53            }
54            fn get_token(&self, index: usize) -> Option<Token<LuaSyntaxKind>> {
55                self.tokens.get(index).cloned()
56            }
57            fn count_tokens(&self) -> usize {
58                self.tokens.len()
59            }
60            fn has_tokens(&self) -> bool {
61                !self.tokens.is_empty()
62            }
63        }
64
65        let config = crate::language::LuaLanguage::default();
66        let lexer = LuaLexer::new(&config);
67        let mut cache = SimpleCache { tokens: Vec::new() };
68        let source = SourceText::new(text);
69        let output = lexer.lex(&source, &[], &mut cache);
70
71        if let Ok(tokens) = output.result {
72            for token in tokens.iter() {
73                let kind = match token.kind {
74                    LuaSyntaxKind::And
75                    | LuaSyntaxKind::Break
76                    | LuaSyntaxKind::Do
77                    | LuaSyntaxKind::Else
78                    | LuaSyntaxKind::Elseif
79                    | LuaSyntaxKind::End
80                    | LuaSyntaxKind::False
81                    | LuaSyntaxKind::For
82                    | LuaSyntaxKind::Function
83                    | LuaSyntaxKind::Goto
84                    | LuaSyntaxKind::If
85                    | LuaSyntaxKind::In
86                    | LuaSyntaxKind::Local
87                    | LuaSyntaxKind::Nil
88                    | LuaSyntaxKind::Not
89                    | LuaSyntaxKind::Or
90                    | LuaSyntaxKind::Repeat
91                    | LuaSyntaxKind::Return
92                    | LuaSyntaxKind::Then
93                    | LuaSyntaxKind::True
94                    | LuaSyntaxKind::Until
95                    | LuaSyntaxKind::While => Some(HighlightKind::Keyword),
96                    LuaSyntaxKind::String => Some(HighlightKind::String),
97                    LuaSyntaxKind::Number => Some(HighlightKind::Number),
98                    LuaSyntaxKind::Comment => Some(HighlightKind::Comment),
99                    LuaSyntaxKind::Identifier => Some(HighlightKind::Identifier),
100                    LuaSyntaxKind::Plus
101                    | LuaSyntaxKind::Minus
102                    | LuaSyntaxKind::Star
103                    | LuaSyntaxKind::Slash
104                    | LuaSyntaxKind::Percent
105                    | LuaSyntaxKind::Caret
106                    | LuaSyntaxKind::Hash
107                    | LuaSyntaxKind::EqEq
108                    | LuaSyntaxKind::TildeEq
109                    | LuaSyntaxKind::LtEq
110                    | LuaSyntaxKind::GtEq
111                    | LuaSyntaxKind::Lt
112                    | LuaSyntaxKind::Gt
113                    | LuaSyntaxKind::Eq => Some(HighlightKind::Operator),
114                    _ => None,
115                };
116
117                if let Some(h_kind) = kind {
118                    highlights.push((token.span.start, token.span.end, h_kind));
119                }
120            }
121        }
122
123        highlights
124    }
125}