reedline/completion/
history.rs1use std::ops::Deref;
2
3use crate::{
4 history::SearchQuery, menu_functions::parse_selection_char, Completer, History, Span,
5 Suggestion,
6};
7
8const SELECTION_CHAR: char = '!';
9
10pub(crate) struct HistoryCompleter<'menu>(&'menu dyn History);
13
14unsafe impl<'menu> Send for HistoryCompleter<'menu> {}
17
18impl<'menu> Completer for HistoryCompleter<'menu> {
19 fn complete(&mut self, line: &str, pos: usize) -> Vec<Suggestion> {
20 let parsed = parse_selection_char(line, SELECTION_CHAR);
21 let values = self
22 .0
23 .search(SearchQuery::all_that_contain_rev(
24 parsed.remainder.to_string(),
25 ))
26 .expect("todo: error handling");
27
28 values
29 .into_iter()
30 .map(|value| self.create_suggestion(line, pos, value.command_line.deref()))
31 .collect()
32 }
33
34 fn total_completions(&mut self, line: &str, _pos: usize) -> usize {
37 let parsed = parse_selection_char(line, SELECTION_CHAR);
38 let count = self
39 .0
40 .count(SearchQuery::all_that_contain_rev(
41 parsed.remainder.to_string(),
42 ))
43 .expect("todo: error handling");
44 count as usize
45 }
46}
47
48impl<'menu> HistoryCompleter<'menu> {
49 pub fn new(history: &'menu dyn History) -> Self {
50 Self(history)
51 }
52
53 fn create_suggestion(&self, line: &str, pos: usize, value: &str) -> Suggestion {
54 let span = Span {
55 start: pos,
56 end: pos + line.len(),
57 };
58
59 Suggestion {
60 value: value.to_string(),
61 description: None,
62 extra: None,
63 span,
64 append_whitespace: false,
65 }
66 }
67}