matching_brackets_highlighters/
matching_brackets_highlighters.rs

1use lineeditor::style::Style;
2use lineeditor::styled_buffer::StyledBuffer;
3use lineeditor::Color;
4use lineeditor::Highlighter;
5use lineeditor::LineEditor;
6use lineeditor::LineEditorResult;
7use lineeditor::StringPrompt;
8
9#[derive(Default)]
10pub struct MatchingBracketsHighlighter {}
11
12impl Highlighter for MatchingBracketsHighlighter {
13    fn highlight(&self, buffer: &mut StyledBuffer) {
14        let colors = vec![Color::Red, Color::Blue, Color::Yellow, Color::Green];
15        let mut brackets_stack: Vec<Color> = vec![];
16        let mut current_color_index = 0;
17
18        let lines = buffer.buffer().clone();
19        let mut i: usize = 0;
20        loop {
21            if i >= lines.len() {
22                break;
23            }
24
25            if lines[i] == '"' {
26                i += 1;
27                while i < lines.len() && lines[i] != '"' {
28                    i += 1;
29                }
30
31                if i < lines.len() {
32                    i += 1;
33                }
34                continue;
35            }
36
37            if lines[i] == '(' || lines[i] == '<' || lines[i] == '[' || lines[i] == '{' {
38                if current_color_index >= colors.len() {
39                    current_color_index = 0;
40                }
41
42                let color = colors[current_color_index];
43                current_color_index += 1;
44
45                brackets_stack.push(color);
46
47                let mut style = Style::default();
48                style.set_foreground_color(color);
49                buffer.style_char(i, style);
50                i += 1;
51                continue;
52            }
53
54            if lines[i] == ')' || lines[i] == '>' || lines[i] == ']' || lines[i] == '}' {
55                let color = if brackets_stack.is_empty() {
56                    colors[0]
57                } else {
58                    brackets_stack.pop().unwrap()
59                };
60
61                let mut style = Style::default();
62                style.set_foreground_color(color);
63                buffer.style_char(i, style);
64
65                i += 1;
66                continue;
67            }
68            i += 1;
69        }
70    }
71}
72
73fn main() {
74    let prompt = StringPrompt::new("gql> ".to_string());
75    let mut line_editor = LineEditor::new(Box::new(prompt));
76    line_editor.add_highlighter(Box::<MatchingBracketsHighlighter>::default());
77
78    let bindings = line_editor.keybinding();
79    bindings.register_common_control_bindings();
80
81    match line_editor.read_line() {
82        Ok(LineEditorResult::Success(line)) => {
83            println!("Line {}", line);
84        }
85        _ => {}
86    }
87}