reedline/highlighter/
example.rs

1use crate::highlighter::Highlighter;
2use crate::StyledText;
3use nu_ansi_term::{Color, Style};
4
5pub static DEFAULT_BUFFER_MATCH_COLOR: Color = Color::Green;
6pub static DEFAULT_BUFFER_NEUTRAL_COLOR: Color = Color::White;
7pub static DEFAULT_BUFFER_NOTMATCH_COLOR: Color = Color::Red;
8
9/// A simple, example highlighter that shows how to highlight keywords
10pub struct ExampleHighlighter {
11    external_commands: Vec<String>,
12    match_color: Color,
13    notmatch_color: Color,
14    neutral_color: Color,
15}
16
17impl Highlighter for ExampleHighlighter {
18    fn highlight(&self, line: &str, _cursor: usize) -> StyledText {
19        let mut styled_text = StyledText::new();
20
21        if self
22            .external_commands
23            .clone()
24            .iter()
25            .any(|x| line.contains(x))
26        {
27            let matches: Vec<&str> = self
28                .external_commands
29                .iter()
30                .filter(|c| line.contains(*c))
31                .map(std::ops::Deref::deref)
32                .collect();
33            let longest_match = matches.iter().fold("".to_string(), |acc, &item| {
34                if item.len() > acc.len() {
35                    item.to_string()
36                } else {
37                    acc
38                }
39            });
40            let buffer_split: Vec<&str> = line.splitn(2, &longest_match).collect();
41
42            styled_text.push((
43                Style::new().fg(self.neutral_color),
44                buffer_split[0].to_string(),
45            ));
46            styled_text.push((Style::new().fg(self.match_color), longest_match));
47            styled_text.push((
48                Style::new().bold().fg(self.neutral_color),
49                buffer_split[1].to_string(),
50            ));
51        } else if self.external_commands.is_empty() {
52            styled_text.push((Style::new().fg(self.neutral_color), line.to_string()));
53        } else {
54            styled_text.push((Style::new().fg(self.notmatch_color), line.to_string()));
55        }
56
57        styled_text
58    }
59}
60impl ExampleHighlighter {
61    /// Construct the default highlighter with a given set of extern commands/keywords to detect and highlight
62    pub fn new(external_commands: Vec<String>) -> ExampleHighlighter {
63        ExampleHighlighter {
64            external_commands,
65            match_color: DEFAULT_BUFFER_MATCH_COLOR,
66            notmatch_color: DEFAULT_BUFFER_NOTMATCH_COLOR,
67            neutral_color: DEFAULT_BUFFER_NEUTRAL_COLOR,
68        }
69    }
70
71    /// Configure the highlighter to use different colors
72    pub fn change_colors(
73        &mut self,
74        match_color: Color,
75        notmatch_color: Color,
76        neutral_color: Color,
77    ) {
78        self.match_color = match_color;
79        self.notmatch_color = notmatch_color;
80        self.neutral_color = neutral_color;
81    }
82}
83impl Default for ExampleHighlighter {
84    fn default() -> Self {
85        ExampleHighlighter::new(vec![])
86    }
87}