oak_lua/lsp/highlighter/
mod.rs1#![doc = include_str!("readme.md")]
2#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum HighlightKind {
5 Keyword,
7 String,
9 Number,
11 Comment,
13 Macro,
15 Identifier,
17 Operator,
19}
20
21pub trait Highlighter {
23 fn highlight(&self, text: &str) -> Vec<(usize, usize, HighlightKind)>;
25}
26
27pub struct LuaHighlighter;
29
30impl LuaHighlighter {
31 pub fn new() -> Self {
32 Self
33 }
34}
35
36impl Highlighter for LuaHighlighter {
37 fn highlight(&self, text: &str) -> Vec<(usize, usize, HighlightKind)> {
38 let mut highlights = Vec::new();
39
40 use crate::lexer::{LuaLexer, token_type::LuaTokenType};
43 use oak_core::{LexOutput, Lexer, LexerCache, SourceText, Token};
44
45 struct SimpleCache {
46 tokens: Vec<Token<LuaTokenType>>,
47 }
48
49 impl LexerCache<crate::language::LuaLanguage> for SimpleCache {
50 fn set_lex_output(&mut self, output: LexOutput<crate::language::LuaLanguage>) {
51 if let Ok(tokens) = output.result {
52 self.tokens = tokens.to_vec()
53 }
54 }
55 fn get_token(&self, index: usize) -> Option<Token<LuaTokenType>> {
56 self.tokens.get(index).cloned()
57 }
58 fn count_tokens(&self) -> usize {
59 self.tokens.len()
60 }
61 fn has_tokens(&self) -> bool {
62 !self.tokens.is_empty()
63 }
64 }
65
66 let config = crate::language::LuaLanguage::default();
67 let lexer = LuaLexer::new(&config);
68 let mut cache = SimpleCache { tokens: Vec::new() };
69 let source = SourceText::new(text);
70 let output = lexer.lex(&source, &[], &mut cache);
71
72 if let Ok(tokens) = output.result {
73 for token in tokens.iter() {
74 let kind = match token.kind {
75 LuaTokenType::And
76 | LuaTokenType::Break
77 | LuaTokenType::Do
78 | LuaTokenType::Else
79 | LuaTokenType::Elseif
80 | LuaTokenType::End
81 | LuaTokenType::False
82 | LuaTokenType::For
83 | LuaTokenType::Function
84 | LuaTokenType::Goto
85 | LuaTokenType::If
86 | LuaTokenType::In
87 | LuaTokenType::Local
88 | LuaTokenType::Nil
89 | LuaTokenType::Not
90 | LuaTokenType::Or
91 | LuaTokenType::Repeat
92 | LuaTokenType::Return
93 | LuaTokenType::Then
94 | LuaTokenType::True
95 | LuaTokenType::Until
96 | LuaTokenType::While => Some(HighlightKind::Keyword),
97 LuaTokenType::String => Some(HighlightKind::String),
98 LuaTokenType::Number => Some(HighlightKind::Number),
99 LuaTokenType::Comment => Some(HighlightKind::Comment),
100 LuaTokenType::Identifier => Some(HighlightKind::Identifier),
101 LuaTokenType::Plus
102 | LuaTokenType::Minus
103 | LuaTokenType::Star
104 | LuaTokenType::Slash
105 | LuaTokenType::Percent
106 | LuaTokenType::Caret
107 | LuaTokenType::Hash
108 | LuaTokenType::EqEq
109 | LuaTokenType::TildeEq
110 | LuaTokenType::LtEq
111 | LuaTokenType::GtEq
112 | LuaTokenType::Lt
113 | LuaTokenType::Gt
114 | LuaTokenType::Eq => Some(HighlightKind::Operator),
115 _ => None,
116 };
117
118 if let Some(h_kind) = kind {
119 highlights.push((token.span.start, token.span.end, h_kind))
120 }
121 }
122 }
123
124 highlights
125 }
126}