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