feat(modulo): implement built-in filter and help text

This commit is contained in:
Federico Terzi 2021-08-18 15:52:48 +02:00
parent 0f361ba6d0
commit 19aab8987e
5 changed files with 66 additions and 2 deletions
espanso-modulo/src

View File

@ -17,14 +17,25 @@
* along with modulo. If not, see <https://www.gnu.org/licenses/>.
*/
use std::collections::HashSet;
use crate::sys::search::types::SearchItem;
pub fn get_algorithm(name: &str) -> Box<dyn Fn(&str, &[SearchItem]) -> Vec<usize>> {
match name {
pub fn get_algorithm(
name: &str,
use_command_filter: bool,
) -> Box<dyn Fn(&str, &[SearchItem]) -> Vec<usize>> {
let search_algorithm: Box<dyn Fn(&str, &[SearchItem]) -> Vec<usize>> = match name {
"exact" => Box::new(exact_match),
"iexact" => Box::new(case_insensitive_exact_match),
"ikey" => Box::new(case_insensitive_keyword),
_ => panic!("unknown search algorithm: {}", name),
};
if use_command_filter {
command_filter(search_algorithm)
} else {
search_algorithm
}
}
@ -78,3 +89,36 @@ fn case_insensitive_keyword(query: &str, items: &[SearchItem]) -> Vec<usize> {
.map(|(i, _)| i)
.collect()
}
fn command_filter(
search_algorithm: Box<dyn Fn(&str, &[SearchItem]) -> Vec<usize>>,
) -> Box<dyn Fn(&str, &[SearchItem]) -> Vec<usize>> {
Box::new(move |query, items| {
let (valid_ids, trimmed_query) = if query.starts_with('>') {
(
items
.iter()
.enumerate()
.filter(|(_, item)| item.is_builtin)
.map(|(i, _)| i).collect::<HashSet<usize>>(),
query.trim_start_matches('>'),
)
} else {
(
items
.iter()
.enumerate()
.filter(|(_, item)| !item.is_builtin)
.map(|(i, _)| i).collect::<HashSet<usize>>(),
query,
)
};
let results = search_algorithm(trimmed_query, &items);
results
.into_iter()
.filter(|id| valid_ids.contains(id))
.collect()
})
}

View File

@ -55,4 +55,7 @@ pub struct SearchItem {
pub id: String,
pub label: String,
pub trigger: Option<String>,
#[serde(default)]
pub is_builtin: bool,
}

View File

@ -28,6 +28,7 @@ pub fn generate(config: SearchConfig) -> types::Search {
id: item.id,
label: item.label,
trigger: item.trigger,
is_builtin: item.is_builtin,
})
.collect();

View File

@ -26,6 +26,7 @@ pub mod types {
pub id: String,
pub label: String,
pub trigger: Option<String>,
pub is_builtin: bool,
}
#[derive(Debug)]

View File

@ -44,6 +44,8 @@ const int SEARCH_BAR_FONT_SIZE = 20;
const long DEFAULT_STYLE = wxSTAY_ON_TOP | wxFRAME_TOOL_WINDOW | wxBORDER_NONE;
#endif
const int HELP_TEXT_FONT_SIZE = 10;
const wxColour SELECTION_LIGHT_BG = wxColour(164, 210, 253);
const wxColour SELECTION_DARK_BG = wxColour(49, 88, 126);
@ -138,6 +140,7 @@ public:
wxPanel *panel;
wxTextCtrl *searchBar;
wxStaticBitmap *iconPanel;
wxStaticText *helpText;
ResultListBox *resultBox;
void SetItems(SearchItem *items, int itemSize);
@ -219,6 +222,12 @@ SearchFrame::SearchFrame(const wxString &title, const wxPoint &pos, const wxSize
vbox->Add(topBox, 1, wxEXPAND);
helpText = new wxStaticText(panel, wxID_ANY, "Search matches by content or trigger (or type > to see commands)");
vbox->Add(helpText, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10);
wxFont helpFont = helpText->GetFont();
helpFont.SetPointSize(HELP_TEXT_FONT_SIZE);
helpText->SetFont(helpFont);
wxArrayString choices;
int resultId = NewControlId();
resultBox = new ResultListBox(panel, isDark, resultId, wxDefaultPosition, wxSize(MIN_WIDTH, MIN_HEIGHT));
@ -299,6 +308,12 @@ void SearchFrame::OnCharEvent(wxKeyEvent &event)
void SearchFrame::OnQueryChange(wxCommandEvent &event)
{
if (helpText != nullptr) {
helpText->Destroy();
panel->Layout();
helpText = nullptr;
}
wxString queryString = searchBar->GetValue();
const char *query = queryString.ToUTF8();
queryCallback(query, (void *)this, data);