reedline/highlighter/
simple_match.rs

1use crate::highlighter::Highlighter;
2use crate::StyledText;
3use nu_ansi_term::{Color, Style};
4
5/// Highlight all matches for a given search string in a line
6///
7/// Default style:
8///
9/// - non-matching text: Default style
10/// - matching text: Green foreground color
11pub struct SimpleMatchHighlighter {
12    neutral_style: Style,
13    match_style: Style,
14    query: String,
15}
16
17impl Default for SimpleMatchHighlighter {
18    fn default() -> Self {
19        Self {
20            neutral_style: Style::default(),
21            match_style: Style::new().fg(Color::Green),
22            query: String::default(),
23        }
24    }
25}
26
27impl Highlighter for SimpleMatchHighlighter {
28    fn highlight(&self, line: &str, _cursor: usize) -> StyledText {
29        let mut styled_text = StyledText::new();
30        if self.query.is_empty() {
31            styled_text.push((self.neutral_style, line.to_owned()));
32        } else {
33            let mut next_idx: usize = 0;
34
35            for (idx, mat) in line.match_indices(&self.query) {
36                if idx != next_idx {
37                    styled_text.push((self.neutral_style, line[next_idx..idx].to_owned()));
38                }
39                styled_text.push((self.match_style, mat.to_owned()));
40                next_idx = idx + mat.len();
41            }
42            if next_idx != line.len() {
43                styled_text.push((self.neutral_style, line[next_idx..].to_owned()));
44            }
45        }
46        styled_text
47    }
48}
49
50impl SimpleMatchHighlighter {
51    /// Create a simple highlighter that styles every exact match of `query`.
52    pub fn new(query: String) -> Self {
53        Self {
54            query,
55            ..Self::default()
56        }
57    }
58
59    /// Update query string to match
60    #[must_use]
61    pub fn with_query(mut self, query: String) -> Self {
62        self.query = query;
63        self
64    }
65
66    /// Set style for the matches found
67    #[must_use]
68    pub fn with_match_style(mut self, match_style: Style) -> Self {
69        self.match_style = match_style;
70        self
71    }
72
73    /// Set style for the text that does not match the query
74    #[must_use]
75    pub fn with_neutral_style(mut self, neutral_style: Style) -> Self {
76        self.neutral_style = neutral_style;
77        self
78    }
79}