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