From 94a276d9e8a4215af95334a45b64a5923616abf6 Mon Sep 17 00:00:00 2001 From: Cezar Craciun Date: Thu, 13 Jan 2022 23:52:15 +0200 Subject: [PATCH 1/3] Limit the number of visible options in fuzzy select --- examples/fuzzyselect.rs | 24 ++++++++++++++++++++++++ src/prompts/fuzzy_select.rs | 7 +++++++ 2 files changed, 31 insertions(+) diff --git a/examples/fuzzyselect.rs b/examples/fuzzyselect.rs index 93b9b623..a00fb6b1 100644 --- a/examples/fuzzyselect.rs +++ b/examples/fuzzyselect.rs @@ -6,6 +6,30 @@ fn main() { "Vanilla Cupcake", "Chocolate Muffin", "A Pile of sweet, sweet mustard", + "Carrots", + "Peas", + "Pistacio", + "Mustard", + "Cream", + "Banana", + "Chocolate", + "Flakes", + "Corn", + "Cake", + "Tarte", + "Cheddar", + "Vanilla", + "Hazelnut", + "Flour", + "Sugar", + "Salt", + "Potato", + "French Fries", + "Pizza", + "Mousse au chocolat", + "Brown sugar", + "Blueberry", + "Burger", ]; let selection = FuzzySelect::with_theme(&ColorfulTheme::default()) diff --git a/src/prompts/fuzzy_select.rs b/src/prompts/fuzzy_select.rs index 4d423e49..155ebd29 100644 --- a/src/prompts/fuzzy_select.rs +++ b/src/prompts/fuzzy_select.rs @@ -152,6 +152,12 @@ impl FuzzySelect<'_> { // Fuzzy matcher let matcher = fuzzy_matcher::skim::SkimMatcherV2::default(); + let term_size_rows = term.size().0 as usize; + // Subtract -2 because we need space to render the prompt. + let visible_term_rows = term_size_rows + .max(3) // Safeguard in case term_size_rows is 2 or less. + - 2; + term.hide_cursor()?; loop { @@ -164,6 +170,7 @@ impl FuzzySelect<'_> { .iter() .map(|item| (item, matcher.fuzzy_match(item, &search_term))) .filter_map(|(item, score)| score.map(|s| (item, s))) + .take(visible_term_rows) .collect::>(); // Renders all matching items, from best match to worst. From f1e46a55e938d662ace31f6b8b0a8644ba388122 Mon Sep 17 00:00:00 2001 From: Cezar Craciun Date: Fri, 14 Jan 2022 21:32:04 +0200 Subject: [PATCH 2/3] Add scroll functionality --- src/prompts/fuzzy_select.rs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/prompts/fuzzy_select.rs b/src/prompts/fuzzy_select.rs index 155ebd29..cab4a0db 100644 --- a/src/prompts/fuzzy_select.rs +++ b/src/prompts/fuzzy_select.rs @@ -152,11 +152,10 @@ impl FuzzySelect<'_> { // Fuzzy matcher let matcher = fuzzy_matcher::skim::SkimMatcherV2::default(); - let term_size_rows = term.size().0 as usize; // Subtract -2 because we need space to render the prompt. - let visible_term_rows = term_size_rows - .max(3) // Safeguard in case term_size_rows is 2 or less. - - 2; + let visible_term_rows = (term.size().0 as usize).max(3) - 2; + // Variable used to determine if we need to scroll through the list. + let mut starting_row = 0; term.hide_cursor()?; @@ -170,13 +169,17 @@ impl FuzzySelect<'_> { .iter() .map(|item| (item, matcher.fuzzy_match(item, &search_term))) .filter_map(|(item, score)| score.map(|s| (item, s))) - .take(visible_term_rows) .collect::>(); // Renders all matching items, from best match to worst. filtered_list.sort_unstable_by(|(_, s1), (_, s2)| s2.cmp(&s1)); - for (idx, (item, _)) in filtered_list.iter().enumerate() { + for (idx, (item, _)) in filtered_list + .iter() + .enumerate() + .skip(starting_row) + .take(visible_term_rows) + { render.select_prompt_item(item, idx == sel)?; term.flush()?; } @@ -191,6 +194,12 @@ impl FuzzySelect<'_> { return Ok(None); } Key::ArrowUp | Key::BackTab if filtered_list.len() > 0 => { + if sel == 0 { + starting_row = + filtered_list.len().max(visible_term_rows) - visible_term_rows; + } else if sel == starting_row { + starting_row -= 1; + } if sel == !0 { sel = filtered_list.len() - 1; } else { @@ -205,6 +214,11 @@ impl FuzzySelect<'_> { } else { sel = (sel as u64 + 1).rem(filtered_list.len() as u64) as usize; } + if sel == visible_term_rows + starting_row { + starting_row += 1; + } else if sel == 0 { + starting_row = 0; + } term.flush()?; } Key::ArrowLeft if position > 0 => { @@ -242,6 +256,7 @@ impl FuzzySelect<'_> { position += 1; term.flush()?; sel = 0; + starting_row = 0; } _ => {} From 252a183fe07359c02bc8e165f53e735376069580 Mon Sep 17 00:00:00 2001 From: Cezar Craciun Date: Fri, 14 Jan 2022 21:33:56 +0200 Subject: [PATCH 3/3] Fix linting warnings --- src/prompts/fuzzy_select.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/prompts/fuzzy_select.rs b/src/prompts/fuzzy_select.rs index cab4a0db..e17b4908 100644 --- a/src/prompts/fuzzy_select.rs +++ b/src/prompts/fuzzy_select.rs @@ -146,7 +146,7 @@ impl FuzzySelect<'_> { let mut size_vec = Vec::new(); for items in self.items.iter().as_slice() { let size = &items.len(); - size_vec.push(size.clone()); + size_vec.push(*size); } // Fuzzy matcher @@ -172,7 +172,7 @@ impl FuzzySelect<'_> { .collect::>(); // Renders all matching items, from best match to worst. - filtered_list.sort_unstable_by(|(_, s1), (_, s2)| s2.cmp(&s1)); + filtered_list.sort_unstable_by(|(_, s1), (_, s2)| s2.cmp(s1)); for (idx, (item, _)) in filtered_list .iter() @@ -193,7 +193,7 @@ impl FuzzySelect<'_> { term.show_cursor()?; return Ok(None); } - Key::ArrowUp | Key::BackTab if filtered_list.len() > 0 => { + Key::ArrowUp | Key::BackTab if !filtered_list.is_empty() => { if sel == 0 { starting_row = filtered_list.len().max(visible_term_rows) - visible_term_rows; @@ -208,7 +208,7 @@ impl FuzzySelect<'_> { } term.flush()?; } - Key::ArrowDown | Key::Tab if filtered_list.len() > 0 => { + Key::ArrowDown | Key::Tab if !filtered_list.is_empty() => { if sel == !0 { sel = 0; } else { @@ -229,14 +229,14 @@ impl FuzzySelect<'_> { position += 1; term.flush()?; } - Key::Enter if filtered_list.len() > 0 => { + Key::Enter if !filtered_list.is_empty() => { if self.clear { render.clear()?; } if self.report { render - .input_prompt_selection(self.prompt.as_str(), &filtered_list[sel].0)?; + .input_prompt_selection(self.prompt.as_str(), filtered_list[sel].0)?; } let sel_string = filtered_list[sel].0;