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