Skip to content

Commit c93224a

Browse files
authored
Merge pull request #162 from craciuncezar/limit-visible-options-in-fuzzy-select
2 parents dee84e9 + 252a183 commit c93224a

File tree

2 files changed

+53
-7
lines changed

2 files changed

+53
-7
lines changed

examples/fuzzyselect.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,30 @@ fn main() {
66
"Vanilla Cupcake",
77
"Chocolate Muffin",
88
"A Pile of sweet, sweet mustard",
9+
"Carrots",
10+
"Peas",
11+
"Pistacio",
12+
"Mustard",
13+
"Cream",
14+
"Banana",
15+
"Chocolate",
16+
"Flakes",
17+
"Corn",
18+
"Cake",
19+
"Tarte",
20+
"Cheddar",
21+
"Vanilla",
22+
"Hazelnut",
23+
"Flour",
24+
"Sugar",
25+
"Salt",
26+
"Potato",
27+
"French Fries",
28+
"Pizza",
29+
"Mousse au chocolat",
30+
"Brown sugar",
31+
"Blueberry",
32+
"Burger",
933
];
1034

1135
let selection = FuzzySelect::with_theme(&ColorfulTheme::default())

src/prompts/fuzzy_select.rs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,17 @@ impl FuzzySelect<'_> {
146146
let mut size_vec = Vec::new();
147147
for items in self.items.iter().as_slice() {
148148
let size = &items.len();
149-
size_vec.push(size.clone());
149+
size_vec.push(*size);
150150
}
151151

152152
// Fuzzy matcher
153153
let matcher = fuzzy_matcher::skim::SkimMatcherV2::default();
154154

155+
// Subtract -2 because we need space to render the prompt.
156+
let visible_term_rows = (term.size().0 as usize).max(3) - 2;
157+
// Variable used to determine if we need to scroll through the list.
158+
let mut starting_row = 0;
159+
155160
term.hide_cursor()?;
156161

157162
loop {
@@ -167,9 +172,14 @@ impl FuzzySelect<'_> {
167172
.collect::<Vec<_>>();
168173

169174
// Renders all matching items, from best match to worst.
170-
filtered_list.sort_unstable_by(|(_, s1), (_, s2)| s2.cmp(&s1));
175+
filtered_list.sort_unstable_by(|(_, s1), (_, s2)| s2.cmp(s1));
171176

172-
for (idx, (item, _)) in filtered_list.iter().enumerate() {
177+
for (idx, (item, _)) in filtered_list
178+
.iter()
179+
.enumerate()
180+
.skip(starting_row)
181+
.take(visible_term_rows)
182+
{
173183
render.select_prompt_item(item, idx == sel)?;
174184
term.flush()?;
175185
}
@@ -183,7 +193,13 @@ impl FuzzySelect<'_> {
183193
term.show_cursor()?;
184194
return Ok(None);
185195
}
186-
Key::ArrowUp | Key::BackTab if filtered_list.len() > 0 => {
196+
Key::ArrowUp | Key::BackTab if !filtered_list.is_empty() => {
197+
if sel == 0 {
198+
starting_row =
199+
filtered_list.len().max(visible_term_rows) - visible_term_rows;
200+
} else if sel == starting_row {
201+
starting_row -= 1;
202+
}
187203
if sel == !0 {
188204
sel = filtered_list.len() - 1;
189205
} else {
@@ -192,12 +208,17 @@ impl FuzzySelect<'_> {
192208
}
193209
term.flush()?;
194210
}
195-
Key::ArrowDown | Key::Tab if filtered_list.len() > 0 => {
211+
Key::ArrowDown | Key::Tab if !filtered_list.is_empty() => {
196212
if sel == !0 {
197213
sel = 0;
198214
} else {
199215
sel = (sel as u64 + 1).rem(filtered_list.len() as u64) as usize;
200216
}
217+
if sel == visible_term_rows + starting_row {
218+
starting_row += 1;
219+
} else if sel == 0 {
220+
starting_row = 0;
221+
}
201222
term.flush()?;
202223
}
203224
Key::ArrowLeft if position > 0 => {
@@ -208,14 +229,14 @@ impl FuzzySelect<'_> {
208229
position += 1;
209230
term.flush()?;
210231
}
211-
Key::Enter if filtered_list.len() > 0 => {
232+
Key::Enter if !filtered_list.is_empty() => {
212233
if self.clear {
213234
render.clear()?;
214235
}
215236

216237
if self.report {
217238
render
218-
.input_prompt_selection(self.prompt.as_str(), &filtered_list[sel].0)?;
239+
.input_prompt_selection(self.prompt.as_str(), filtered_list[sel].0)?;
219240
}
220241

221242
let sel_string = filtered_list[sel].0;
@@ -235,6 +256,7 @@ impl FuzzySelect<'_> {
235256
position += 1;
236257
term.flush()?;
237258
sel = 0;
259+
starting_row = 0;
238260
}
239261

240262
_ => {}

0 commit comments

Comments
 (0)