@@ -146,12 +146,17 @@ impl FuzzySelect<'_> {
146
146
let mut size_vec = Vec :: new ( ) ;
147
147
for items in self . items . iter ( ) . as_slice ( ) {
148
148
let size = & items. len ( ) ;
149
- size_vec. push ( size. clone ( ) ) ;
149
+ size_vec. push ( * size) ;
150
150
}
151
151
152
152
// Fuzzy matcher
153
153
let matcher = fuzzy_matcher:: skim:: SkimMatcherV2 :: default ( ) ;
154
154
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
+
155
160
term. hide_cursor ( ) ?;
156
161
157
162
loop {
@@ -167,9 +172,14 @@ impl FuzzySelect<'_> {
167
172
. collect :: < Vec < _ > > ( ) ;
168
173
169
174
// 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) ) ;
171
176
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
+ {
173
183
render. select_prompt_item ( item, idx == sel) ?;
174
184
term. flush ( ) ?;
175
185
}
@@ -183,7 +193,13 @@ impl FuzzySelect<'_> {
183
193
term. show_cursor ( ) ?;
184
194
return Ok ( None ) ;
185
195
}
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
+ }
187
203
if sel == !0 {
188
204
sel = filtered_list. len ( ) - 1 ;
189
205
} else {
@@ -192,12 +208,17 @@ impl FuzzySelect<'_> {
192
208
}
193
209
term. flush ( ) ?;
194
210
}
195
- Key :: ArrowDown | Key :: Tab if filtered_list. len ( ) > 0 => {
211
+ Key :: ArrowDown | Key :: Tab if ! filtered_list. is_empty ( ) => {
196
212
if sel == !0 {
197
213
sel = 0 ;
198
214
} else {
199
215
sel = ( sel as u64 + 1 ) . rem ( filtered_list. len ( ) as u64 ) as usize ;
200
216
}
217
+ if sel == visible_term_rows + starting_row {
218
+ starting_row += 1 ;
219
+ } else if sel == 0 {
220
+ starting_row = 0 ;
221
+ }
201
222
term. flush ( ) ?;
202
223
}
203
224
Key :: ArrowLeft if position > 0 => {
@@ -208,14 +229,14 @@ impl FuzzySelect<'_> {
208
229
position += 1 ;
209
230
term. flush ( ) ?;
210
231
}
211
- Key :: Enter if filtered_list. len ( ) > 0 => {
232
+ Key :: Enter if ! filtered_list. is_empty ( ) => {
212
233
if self . clear {
213
234
render. clear ( ) ?;
214
235
}
215
236
216
237
if self . report {
217
238
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 ) ?;
219
240
}
220
241
221
242
let sel_string = filtered_list[ sel] . 0 ;
@@ -235,6 +256,7 @@ impl FuzzySelect<'_> {
235
256
position += 1 ;
236
257
term. flush ( ) ?;
237
258
sel = 0 ;
259
+ starting_row = 0 ;
238
260
}
239
261
240
262
_ => { }
0 commit comments