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 lexer = LuaLexer::new(&crate::language::LuaLanguage::default());
66        let mut cache = SimpleCache { tokens: Vec::new() };
67        let source = SourceText::new(text);
68        let output = lexer.lex(&source, &[], &mut cache);
69
70        if let Ok(tokens) = output.result {
71            for token in tokens.iter() {
72                let kind = match token.kind {
73                    LuaSyntaxKind::And
74                    | LuaSyntaxKind::Break
75                    | LuaSyntaxKind::Do
76                    | LuaSyntaxKind::Else
77                    | LuaSyntaxKind::Elseif
78                    | LuaSyntaxKind::End
79                    | LuaSyntaxKind::False
80                    | LuaSyntaxKind::For
81                    | LuaSyntaxKind::Function
82                    | LuaSyntaxKind::Goto
83                    | LuaSyntaxKind::If
84                    | LuaSyntaxKind::In
85                    | LuaSyntaxKind::Local
86                    | LuaSyntaxKind::Nil
87                    | LuaSyntaxKind::Not
88                    | LuaSyntaxKind::Or
89                    | LuaSyntaxKind::Repeat
90                    | LuaSyntaxKind::Return
91                    | LuaSyntaxKind::Then
92                    | LuaSyntaxKind::True
93                    | LuaSyntaxKind::Until
94                    | LuaSyntaxKind::While => Some(HighlightKind::Keyword),
95                    LuaSyntaxKind::String => Some(HighlightKind::String),
96                    LuaSyntaxKind::Number => Some(HighlightKind::Number),
97                    LuaSyntaxKind::Comment => Some(HighlightKind::Comment),
98                    LuaSyntaxKind::Identifier => Some(HighlightKind::Identifier),
99                    LuaSyntaxKind::Plus
100                    | LuaSyntaxKind::Minus
101                    | LuaSyntaxKind::Star
102                    | LuaSyntaxKind::Slash
103                    | LuaSyntaxKind::Percent
104                    | LuaSyntaxKind::Caret
105                    | LuaSyntaxKind::Hash
106                    | LuaSyntaxKind::EqEq
107                    | LuaSyntaxKind::TildeEq
108                    | LuaSyntaxKind::LtEq
109                    | LuaSyntaxKind::GtEq
110                    | LuaSyntaxKind::Lt
111                    | LuaSyntaxKind::Gt
112                    | LuaSyntaxKind::Eq => Some(HighlightKind::Operator),
113                    _ => None,
114                };
115
116                if let Some(h_kind) = kind {
117                    highlights.push((token.span.start, token.span.end, h_kind));
118                }
119            }
120        }
121
122        highlights
123    }
124}