oak_powershell/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 Identifier,
15}
16
17pub trait Highlighter {
19 fn highlight(&self, text: &str) -> Vec<(usize, usize, HighlightKind)>;
21}
22
23pub struct PowerShellHighlighter {
25 pub use_parser: bool,
27}
28
29impl Default for PowerShellHighlighter {
30 fn default() -> Self {
31 Self { use_parser: false }
32 }
33}
34
35impl PowerShellHighlighter {
36 pub fn new() -> Self {
38 Self::default()
39 }
40
41 pub fn with_parser() -> Self {
43 Self { use_parser: true }
44 }
45
46 fn highlight_keywords(&self, text: &str) -> Vec<(usize, usize, HighlightKind)> {
47 let mut highlights = Vec::new();
48 let keywords = [
49 "begin",
50 "break",
51 "catch",
52 "class",
53 "continue",
54 "data",
55 "define",
56 "do",
57 "dynamicparam",
58 "else",
59 "elseif",
60 "end",
61 "exit",
62 "filter",
63 "finally",
64 "for",
65 "foreach",
66 "from",
67 "function",
68 "if",
69 "in",
70 "inline",
71 "parallel",
72 "param",
73 "process",
74 "return",
75 "switch",
76 "throw",
77 "trap",
78 "try",
79 "until",
80 "using",
81 "var",
82 "while",
83 "workflow",
84 ];
85
86 for keyword in &keywords {
87 let mut start = 0;
88 while let Some(pos) = text[start..].to_lowercase().find(&keyword.to_lowercase()) {
89 let absolute_pos = start + pos;
90 let end_pos = absolute_pos + keyword.len();
91
92 let is_word_boundary_before = absolute_pos == 0 || !text.chars().nth(absolute_pos - 1).unwrap_or(' ').is_alphanumeric();
93 let is_word_boundary_after = end_pos >= text.len() || !text.chars().nth(end_pos).unwrap_or(' ').is_alphanumeric();
94
95 if is_word_boundary_before && is_word_boundary_after {
96 highlights.push((absolute_pos, end_pos, HighlightKind::Keyword));
97 }
98
99 start = absolute_pos + 1;
100 }
101 }
102
103 highlights
104 }
105}
106
107impl Highlighter for PowerShellHighlighter {
108 fn highlight(&self, text: &str) -> Vec<(usize, usize, HighlightKind)> {
109 let mut highlights = self.highlight_keywords(text);
110 highlights.sort_by_key(|h| h.0);
111 highlights
112 }
113}