Skip to content

Commit 3b22a4f

Browse files
authored
Simplify code for moving selection (#2645)
1 parent 534da90 commit 3b22a4f

File tree

1 file changed

+61
-91
lines changed

1 file changed

+61
-91
lines changed

filetreelist/src/filetree.rs

Lines changed: 61 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
2127
pub 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

Comments
 (0)