keyword_highlighter/
keyword_highlighter.rs1use lineeditor::style::Style;
2use lineeditor::styled_buffer::StyledBuffer;
3use lineeditor::Color;
4use lineeditor::Highlighter;
5use lineeditor::LineEditor;
6use lineeditor::LineEditorResult;
7use lineeditor::StringPrompt;
8
9const GITQL_RESERVED_KEYWORDS: [&str; 31] = [
10 "set", "select", "distinct", "from", "group", "where", "having", "offset", "limit", "order",
11 "by", "case", "when", "then", "else", "end", "between", "in", "is", "not", "like", "glob",
12 "or", "and", "xor", "true", "false", "null", "as", "asc", "desc",
13];
14
15#[derive(Default)]
16pub struct GitQLHighlighter {}
17
18impl Highlighter for GitQLHighlighter {
19 fn highlight(&self, buffer: &mut StyledBuffer) {
20 let lines = buffer.buffer().clone();
21 let mut i: usize = 0;
22
23 let mut keyword_style = Style::default();
24 keyword_style.set_foreground_color(Color::Magenta);
25
26 let mut string_style = Style::default();
27 string_style.set_foreground_color(Color::Yellow);
28
29 loop {
30 if i >= lines.len() {
31 break;
32 }
33
34 if lines[i] == '"' {
36 buffer.style_char(i, string_style.clone());
37 i += 1;
38
39 while i < lines.len() && lines[i] != '"' {
40 buffer.style_char(i, string_style.clone());
41 i += 1;
42 }
43
44 if i < lines.len() && lines[i] == '"' {
45 buffer.style_char(i, string_style.clone());
46 i += 1;
47 }
48
49 continue;
50 }
51
52 if lines[i].is_alphabetic() {
54 let start = i;
55 let mut keyword = String::new();
56 while i < lines.len() && (lines[i].is_alphanumeric() || lines[i] == '_') {
57 keyword.push(lines[i]);
58 i += 1;
59 }
60
61 keyword = keyword.to_lowercase();
62 if GITQL_RESERVED_KEYWORDS.contains(&keyword.as_str()) {
63 buffer.style_range(start, i, keyword_style.clone())
64 }
65 continue;
66 }
67
68 i += 1;
69 }
70 }
71}
72
73fn main() {
74 let prompt = StringPrompt::new("prompt> ".to_string());
75 let mut line_editor = LineEditor::new(Box::new(prompt));
76
77 let bindings = line_editor.keybinding();
78 bindings.register_common_control_bindings();
79
80 line_editor.add_highlighter(Box::<GitQLHighlighter>::default());
81
82 match line_editor.read_line() {
83 Ok(LineEditorResult::Success(line)) => {
84 println!("Line {}", line);
85 }
86 _ => {}
87 }
88}