Skip to main content

oak_actionscript/lsp/highlighter/
mod.rs

1#![doc = include_str!("readme.md")]
2
3/// Local definition of highlight types.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum HighlightKind {
6    /// Keyword.
7    Keyword,
8    /// String.
9    String,
10    /// Number.
11    Number,
12    /// Comment.
13    Comment,
14    /// Identifier.
15    Identifier,
16}
17
18/// ActionScript syntax highlighter.
19pub struct ActionScriptHighlighter {
20    /// Whether to use parser-based highlighting.
21    pub use_parser: bool,
22}
23
24impl Default for ActionScriptHighlighter {
25    fn default() -> Self {
26        Self { use_parser: false }
27    }
28}
29
30impl ActionScriptHighlighter {
31    /// Creates a new ActionScript highlighter instance.
32    pub fn new() -> Self {
33        Self::default()
34    }
35
36    /// Highlights the given text.
37    pub fn highlight(&self, text: &str) -> Vec<(usize, usize, HighlightKind)> {
38        let mut highlights = Vec::new();
39        highlights.extend(self.highlight_keywords(text));
40        highlights
41    }
42
43    fn highlight_keywords(&self, text: &str) -> Vec<(usize, usize, HighlightKind)> {
44        let mut highlights = Vec::new();
45        let keywords = [
46            "as",
47            "break",
48            "case",
49            "catch",
50            "class",
51            "const",
52            "continue",
53            "default",
54            "delete",
55            "do",
56            "else",
57            "extends",
58            "false",
59            "finally",
60            "for",
61            "function",
62            "if",
63            "implements",
64            "import",
65            "in",
66            "instanceof",
67            "interface",
68            "internal",
69            "is",
70            "native",
71            "new",
72            "null",
73            "package",
74            "private",
75            "protected",
76            "public",
77            "return",
78            "set",
79            "static",
80            "super",
81            "switch",
82            "this",
83            "throw",
84            "true",
85            "try",
86            "typeof",
87            "use",
88            "var",
89            "void",
90            "while",
91            "with",
92            "dynamic",
93            "final",
94            "native",
95            "override",
96            "static",
97            "abstract",
98            "virtual",
99        ];
100
101        for keyword in &keywords {
102            let mut start = 0;
103            while let Some(pos) = text[start..].find(keyword) {
104                let absolute_pos = start + pos;
105                let end_pos = absolute_pos + keyword.len();
106
107                let is_word_boundary_before = absolute_pos == 0 || !text.chars().nth(absolute_pos - 1).unwrap_or(' ').is_alphanumeric();
108                let is_word_boundary_after = end_pos >= text.len() || !text.chars().nth(end_pos).unwrap_or(' ').is_alphanumeric();
109
110                if is_word_boundary_before && is_word_boundary_after {
111                    highlights.push((absolute_pos, end_pos, HighlightKind::Keyword))
112                }
113
114                start = absolute_pos + 1
115            }
116        }
117
118        highlights
119    }
120}