Skip to main content

oak_ruby/lsp/highlighter/
mod.rs

1#![doc = include_str!("readme.md")]
2//! Ruby syntax highlighter
3//!
4//! This module provides syntax highlighting for Ruby source code.
5
6/// Ruby syntax highlighter
7pub struct RubyHighlighter {
8    /// Whether to use parser-based highlighting for better accuracy
9    pub use_parser: bool,
10}
11
12impl Default for RubyHighlighter {
13    fn default() -> Self {
14        Self { use_parser: false }
15    }
16}
17
18impl RubyHighlighter {
19    /// Creates a new Ruby highlighter instance
20    pub fn new() -> Self {
21        Self::default()
22    }
23
24    /// Highlights Ruby keywords
25    pub fn highlight(&self, text: &str) -> Vec<(usize, usize, String)> {
26        let mut highlights = Vec::new();
27        let keywords = [
28            "if", "unless", "elsif", "else", "case", "when", "then", "for", "while", "until", "break", "next", "redo", "retry", "return", "yield", "def", "class", "module", "end", "lambda", "proc", "begin", "rescue", "ensure", "raise", "require", "load",
29            "include", "extend", "prepend", "and", "or", "not", "in", "true", "false", "nil", "super", "self", "alias", "undef", "defined", "do",
30        ];
31
32        for keyword in &keywords {
33            let mut start = 0;
34            while let Some(pos) = text[start..].find(keyword) {
35                let absolute_pos = start + pos;
36                let end_pos = absolute_pos + keyword.len();
37
38                let is_word_boundary_before = absolute_pos == 0 || !text.chars().nth(absolute_pos - 1).unwrap_or(' ').is_alphanumeric();
39                let is_word_boundary_after = end_pos >= text.len() || !text.chars().nth(end_pos).unwrap_or(' ').is_alphanumeric();
40
41                if is_word_boundary_before && is_word_boundary_after {
42                    highlights.push((absolute_pos, end_pos, "keyword".to_string()))
43                }
44                start = absolute_pos + 1
45            }
46        }
47        highlights
48    }
49}