diff options
Diffstat (limited to 'ui/src/components')
-rw-r--r-- | ui/src/components/mail/compose.rs | 3 | ||||
-rw-r--r-- | ui/src/components/utilities.rs | 21 | ||||
-rw-r--r-- | ui/src/components/utilities/widgets.rs | 72 |
3 files changed, 84 insertions, 12 deletions
diff --git a/ui/src/components/mail/compose.rs b/ui/src/components/mail/compose.rs index 1b7eab6c..f81b210f 100644 --- a/ui/src/components/mail/compose.rs +++ b/ui/src/components/mail/compose.rs @@ -205,6 +205,9 @@ impl Composer { let book: &AddressBook = &c.accounts[account_cursor].address_book; let results: Vec<String> = book.search(term); results + .into_iter() + .map(|r| AutoCompleteEntry::from(r)) + .collect::<Vec<AutoCompleteEntry>>() }), )); } else { diff --git a/ui/src/components/utilities.rs b/ui/src/components/utilities.rs index 6837d5f5..d538a3a3 100644 --- a/ui/src/components/utilities.rs +++ b/ui/src/components/utilities.rs @@ -699,17 +699,24 @@ impl Component for StatusBar { if self.ex_buffer.as_str().split_graphemes().len() <= 2 { return; } - let suggestions: Vec<String> = self + let mut suggestions: Vec<AutoCompleteEntry> = self .cmd_history .iter() .filter_map(|h| { if h.starts_with(self.ex_buffer.as_str()) { - Some(h.clone()) + Some(h.clone().into()) } else { None } }) .collect(); + suggestions.extend(crate::execute::COMMAND_COMPLETION.iter().filter_map(|e| { + if e.0.starts_with(self.ex_buffer.as_str()) { + Some(e.into()) + } else { + None + } + })); if suggestions.is_empty() && !self.auto_complete.suggestions().is_empty() { self.auto_complete.set_suggestions(suggestions); /* redraw self.container because we have got ridden of an autocomplete @@ -803,7 +810,7 @@ impl Component for StatusBar { .take(hist_height) .enumerate() { - write_string_to_grid( + let (x, y) = write_string_to_grid( s.as_str(), grid, Color::Byte(88), // DarkRed, @@ -817,6 +824,14 @@ impl Component for StatusBar { ), true, ); + write_string_to_grid( + &s.description, + grid, + Color::White, + Color::Byte(174), + ((x + 2, y), bottom_right!(hist_area)), + false, + ); if y_offset + offset == self.auto_complete.cursor() { change_colors( grid, diff --git a/ui/src/components/utilities/widgets.rs b/ui/src/components/utilities/widgets.rs index a3ad1e18..1582668f 100644 --- a/ui/src/components/utilities/widgets.rs +++ b/ui/src/components/utilities/widgets.rs @@ -1,7 +1,7 @@ use super::*; use fnv::FnvHashMap; -type AutoCompleteFn = Box<Fn(&Context, &str) -> Vec<String> + Send>; +type AutoCompleteFn = Box<Fn(&Context, &str) -> Vec<AutoCompleteEntry> + Send>; #[derive(Debug, PartialEq)] enum FormFocus { @@ -576,8 +576,49 @@ where } #[derive(Debug, PartialEq, Clone)] +pub struct AutoCompleteEntry { + pub entry: String, + pub description: String, +} + +impl AutoCompleteEntry { + pub fn as_str(&self) -> &str { + self.entry.as_str() + } +} + +impl From<String> for AutoCompleteEntry { + fn from(val: String) -> Self { + AutoCompleteEntry { + entry: val, + description: String::new(), + } + } +} + +impl From<&(&str, &str)> for AutoCompleteEntry { + fn from(val: &(&str, &str)) -> Self { + let (a, b) = val; + AutoCompleteEntry { + entry: a.to_string(), + description: b.to_string(), + } + } +} + +impl From<(String, String)> for AutoCompleteEntry { + fn from(val: (String, String)) -> Self { + let (a, b) = val; + AutoCompleteEntry { + entry: a, + description: b, + } + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct AutoComplete { - entries: Vec<String>, + entries: Vec<AutoCompleteEntry>, content: CellBuffer, cursor: usize, @@ -637,7 +678,7 @@ impl Component for AutoComplete { } impl AutoComplete { - pub fn new(entries: Vec<String>) -> Self { + pub fn new(entries: Vec<AutoCompleteEntry>) -> Self { let mut ret = AutoComplete { entries: Vec::new(), content: CellBuffer::default(), @@ -649,20 +690,25 @@ impl AutoComplete { ret } - pub fn set_suggestions(&mut self, entries: Vec<String>) -> bool { + pub fn set_suggestions(&mut self, entries: Vec<AutoCompleteEntry>) -> bool { if entries.len() == self.entries.len() && entries == self.entries { return false;; } let mut content = CellBuffer::new( - entries.iter().map(String::len).max().unwrap_or(0) + 1, + entries + .iter() + .map(|a| a.entry.grapheme_len() + a.description.grapheme_len() + 2) + .max() + .unwrap_or(0) + + 1, entries.len(), Cell::with_style(Color::Byte(23), Color::Byte(7), Attr::Default), ); let width = content.cols(); for (i, e) in entries.iter().enumerate() { - write_string_to_grid( - e, + let (x, _) = write_string_to_grid( + &e.entry, &mut content, Color::Byte(23), Color::Byte(7), @@ -670,6 +716,14 @@ impl AutoComplete { false, ); write_string_to_grid( + &e.description, + &mut content, + Color::Byte(23), + Color::Byte(7), + ((x + 2, i), (width - 1, i)), + false, + ); + write_string_to_grid( "▒", &mut content, Color::Byte(23), @@ -712,10 +766,10 @@ impl AutoComplete { self.entries.clear(); self.cursor = 0; self.content.empty(); - Some(ret) + Some(ret.entry) } - pub fn suggestions(&self) -> &Vec<String> { + pub fn suggestions(&self) -> &Vec<AutoCompleteEntry> { &self.entries } } |