@@ -17,6 +17,12 @@ pub enum MoveSelection {
1717 PageUp ,
1818}
1919
20+ #[ derive( Clone , Copy , PartialEq ) ]
21+ enum Direction {
22+ Up ,
23+ Down ,
24+ }
25+
2026#[ derive( Debug , Clone , Copy ) ]
2127pub struct VisualSelection {
2228 pub count : usize ,
@@ -116,40 +122,46 @@ impl FileTree {
116122
117123 fn selection_page_updown (
118124 & self ,
119- range : impl Iterator < Item = usize > ,
125+ current_index : usize ,
126+ direction : Direction ,
120127 ) -> Option < usize > {
121128 let page_size = self . window_height . get ( ) . unwrap_or ( 0 ) ;
122129
123- range
124- . filter ( |index| self . is_visible_index ( * index) )
125- . take ( page_size)
126- . last ( )
130+ if direction == Direction :: Up {
131+ self . get_new_selection (
132+ ( 0 ..=current_index) . rev ( ) ,
133+ page_size,
134+ )
135+ } else {
136+ self . get_new_selection (
137+ current_index..( self . items . len ( ) ) ,
138+ page_size,
139+ )
140+ }
127141 }
128142
129143 ///
130144 pub fn move_selection ( & mut self , dir : MoveSelection ) -> bool {
131145 self . selection . is_some_and ( |selection| {
132146 let new_index = match dir {
133147 MoveSelection :: Up => {
134- self . selection_updown ( selection, true )
148+ self . selection_updown ( selection, Direction :: Up )
135149 }
136150 MoveSelection :: Down => {
137- self . selection_updown ( selection, false )
151+ self . selection_updown ( selection, Direction :: Down )
138152 }
139153 MoveSelection :: Left => self . selection_left ( selection) ,
140154 MoveSelection :: Right => {
141155 self . selection_right ( selection)
142156 }
143- MoveSelection :: Top => {
144- Self :: selection_start ( selection)
145- }
146- MoveSelection :: End => self . selection_end ( selection) ,
147- MoveSelection :: PageUp => {
148- self . selection_page_updown ( ( 0 ..=selection) . rev ( ) )
149- }
157+ MoveSelection :: Top => Some ( 0 ) ,
158+ MoveSelection :: End => self . selection_end ( ) ,
159+ MoveSelection :: PageUp => self
160+ . selection_page_updown ( selection, Direction :: Up ) ,
150161 MoveSelection :: PageDown => self
151162 . selection_page_updown (
152- selection..( self . items . len ( ) ) ,
163+ selection,
164+ Direction :: Down ,
153165 ) ,
154166 } ;
155167
@@ -221,98 +233,53 @@ impl FileTree {
221233 } )
222234 }
223235
224- const fn selection_start ( current_index : usize ) -> Option < usize > {
225- if current_index == 0 {
226- None
227- } else {
228- Some ( 0 )
229- }
230- }
231-
232- fn selection_end ( & self , current_index : usize ) -> Option < usize > {
236+ fn selection_end ( & self ) -> Option < usize > {
233237 let items_max = self . items . len ( ) . saturating_sub ( 1 ) ;
234238
235- let mut new_index = items_max;
236-
237- loop {
238- if self . is_visible_index ( new_index) {
239- break ;
240- }
241-
242- if new_index == 0 {
243- break ;
244- }
245-
246- new_index = new_index. saturating_sub ( 1 ) ;
247- new_index = std:: cmp:: min ( new_index, items_max) ;
248- }
239+ self . get_new_selection ( ( 0 ..=items_max) . rev ( ) , 1 )
240+ }
249241
250- if new_index == current_index {
251- None
252- } else {
253- Some ( new_index)
254- }
242+ fn get_new_selection (
243+ & self ,
244+ range : impl Iterator < Item = usize > ,
245+ take : usize ,
246+ ) -> Option < usize > {
247+ range
248+ . filter ( |index| self . is_visible_index ( * index) )
249+ . take ( take)
250+ . last ( )
255251 }
256252
257253 fn selection_updown (
258254 & self ,
259255 current_index : usize ,
260- up : bool ,
256+ direction : Direction ,
261257 ) -> Option < usize > {
262- let mut index = current_index;
263-
264- loop {
265- index = {
266- let new_index = if up {
267- index. saturating_sub ( 1 )
268- } else {
269- index. saturating_add ( 1 )
270- } ;
271-
272- // when reaching usize bounds
273- if new_index == index {
274- break ;
275- }
276-
277- if new_index >= self . items . len ( ) {
278- break ;
279- }
280-
281- new_index
282- } ;
283-
284- if self . is_visible_index ( index) {
285- break ;
286- }
287- }
288-
289- if index == current_index {
290- None
258+ if direction == Direction :: Up {
259+ self . get_new_selection (
260+ ( 0 ..=current_index. saturating_sub ( 1 ) ) . rev ( ) ,
261+ 1 ,
262+ )
291263 } else {
292- Some ( index)
264+ self . get_new_selection (
265+ ( current_index + 1 ) ..( self . items . len ( ) ) ,
266+ 1 ,
267+ )
293268 }
294269 }
295270
296271 fn select_parent ( & self , current_index : usize ) -> Option < usize > {
297- let indent =
272+ let current_indent =
298273 self . items . tree_items [ current_index] . info ( ) . indent ( ) ;
299274
300- let mut index = current_index;
301-
302- while let Some ( selection) = self . selection_updown ( index, true )
303- {
304- index = selection;
275+ let range = ( 0 ..=current_index) . rev ( ) ;
305276
306- if self . items . tree_items [ index] . info ( ) . indent ( ) < indent {
307- break ;
308- }
309- }
310-
311- if index == current_index {
312- None
313- } else {
314- Some ( index)
315- }
277+ range. filter ( |index| self . is_visible_index ( * index) ) . find (
278+ |index| {
279+ self . items . tree_items [ * index] . info ( ) . indent ( )
280+ < current_indent
281+ } ,
282+ )
316283 }
317284
318285 fn selection_left (
@@ -340,7 +307,10 @@ impl FileTree {
340307 self . items . expand ( current_selection, false ) ;
341308 return Some ( current_selection) ;
342309 }
343- return self . selection_updown ( current_selection, false ) ;
310+ return self . selection_updown (
311+ current_selection,
312+ Direction :: Down ,
313+ ) ;
344314 }
345315
346316 None
0 commit comments