pub mod bracket_match;
mod meta_command;
mod r_regex;
mod r_tree_sitter;
pub use meta_command::MetaCommandHighlighter;
pub use r_regex::TokenType;
pub use r_tree_sitter::{RTreeSitterHighlighter, tokenize_r};
use crate::config::ColorsConfig;
use crate::editor::mode::EditorStateRef;
use nu_ansi_term::Style;
use reedline::{Highlighter, StyledText};
pub struct CombinedHighlighter {
meta_highlighter: MetaCommandHighlighter,
r_highlighter: RTreeSitterHighlighter,
}
impl CombinedHighlighter {
pub fn new(config: ColorsConfig, highlight_matching_bracket: bool) -> Self {
CombinedHighlighter {
meta_highlighter: MetaCommandHighlighter::new(config.meta),
r_highlighter: RTreeSitterHighlighter::new(config.r, highlight_matching_bracket),
}
}
pub fn with_editor_state(mut self, state: EditorStateRef) -> Self {
self.r_highlighter = self.r_highlighter.with_editor_state(state);
self
}
}
impl Default for CombinedHighlighter {
fn default() -> Self {
Self::new(ColorsConfig::default(), true)
}
}
impl Highlighter for CombinedHighlighter {
fn highlight(&self, line: &str, cursor: usize) -> StyledText {
if line.trim_start().starts_with(':') {
self.meta_highlighter.highlight(line, cursor)
} else {
self.r_highlighter.highlight(line, cursor)
}
}
}
#[allow(dead_code)]
pub struct NoHighlighter;
#[allow(dead_code)]
impl NoHighlighter {
pub fn new() -> Self {
NoHighlighter
}
}
impl Default for NoHighlighter {
fn default() -> Self {
Self::new()
}
}
impl Highlighter for NoHighlighter {
fn highlight(&self, line: &str, _cursor: usize) -> StyledText {
let mut styled = StyledText::new();
styled.push((Style::new(), line.to_string()));
styled
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_combined_highlighter_meta_command() {
let highlighter = CombinedHighlighter::default();
let styled = highlighter.highlight(":help", 0);
assert_eq!(styled.raw_string(), ":help");
assert_eq!(styled.buffer.len(), 1);
}
#[test]
fn test_combined_highlighter_r_code() {
let highlighter = CombinedHighlighter::default();
let styled = highlighter.highlight("x <- 42", 0);
assert_eq!(styled.raw_string(), "x <- 42");
assert!(styled.buffer.len() > 1);
}
#[test]
fn test_combined_highlighter_meta_with_whitespace() {
let highlighter = CombinedHighlighter::default();
let styled = highlighter.highlight(" :reprex", 0);
assert_eq!(styled.raw_string(), " :reprex");
}
#[test]
fn test_no_highlighter() {
let highlighter = NoHighlighter::new();
let styled = highlighter.highlight("x <- 42", 0);
assert_eq!(styled.raw_string(), "x <- 42");
assert_eq!(styled.buffer.len(), 1);
}
}