Simplify code for moving selection (#2645)

This commit is contained in:
Christoph Rüßler 2025-05-20 11:15:51 +02:00 committed by GitHub
parent 534da90b12
commit 3b22a4f3b9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -17,6 +17,12 @@ pub enum MoveSelection {
PageUp, PageUp,
} }
#[derive(Clone, Copy, PartialEq)]
enum Direction {
Up,
Down,
}
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct VisualSelection { pub struct VisualSelection {
pub count: usize, pub count: usize,
@ -116,14 +122,22 @@ impl FileTree {
fn selection_page_updown( fn selection_page_updown(
&self, &self,
range: impl Iterator<Item = usize>, current_index: usize,
direction: Direction,
) -> Option<usize> { ) -> Option<usize> {
let page_size = self.window_height.get().unwrap_or(0); let page_size = self.window_height.get().unwrap_or(0);
range if direction == Direction::Up {
.filter(|index| self.is_visible_index(*index)) self.get_new_selection(
.take(page_size) (0..=current_index).rev(),
.last() page_size,
)
} else {
self.get_new_selection(
current_index..(self.items.len()),
page_size,
)
}
} }
/// ///
@ -131,25 +145,23 @@ impl FileTree {
self.selection.is_some_and(|selection| { self.selection.is_some_and(|selection| {
let new_index = match dir { let new_index = match dir {
MoveSelection::Up => { MoveSelection::Up => {
self.selection_updown(selection, true) self.selection_updown(selection, Direction::Up)
} }
MoveSelection::Down => { MoveSelection::Down => {
self.selection_updown(selection, false) self.selection_updown(selection, Direction::Down)
} }
MoveSelection::Left => self.selection_left(selection), MoveSelection::Left => self.selection_left(selection),
MoveSelection::Right => { MoveSelection::Right => {
self.selection_right(selection) self.selection_right(selection)
} }
MoveSelection::Top => { MoveSelection::Top => Some(0),
Self::selection_start(selection) MoveSelection::End => self.selection_end(),
} MoveSelection::PageUp => self
MoveSelection::End => self.selection_end(selection), .selection_page_updown(selection, Direction::Up),
MoveSelection::PageUp => {
self.selection_page_updown((0..=selection).rev())
}
MoveSelection::PageDown => self MoveSelection::PageDown => self
.selection_page_updown( .selection_page_updown(
selection..(self.items.len()), selection,
Direction::Down,
), ),
}; };
@ -221,98 +233,53 @@ impl FileTree {
}) })
} }
const fn selection_start(current_index: usize) -> Option<usize> { fn selection_end(&self) -> Option<usize> {
if current_index == 0 {
None
} else {
Some(0)
}
}
fn selection_end(&self, current_index: usize) -> Option<usize> {
let items_max = self.items.len().saturating_sub(1); let items_max = self.items.len().saturating_sub(1);
let mut new_index = items_max; self.get_new_selection((0..=items_max).rev(), 1)
}
loop { fn get_new_selection(
if self.is_visible_index(new_index) { &self,
break; range: impl Iterator<Item = usize>,
} take: usize,
) -> Option<usize> {
if new_index == 0 { range
break; .filter(|index| self.is_visible_index(*index))
} .take(take)
.last()
new_index = new_index.saturating_sub(1);
new_index = std::cmp::min(new_index, items_max);
}
if new_index == current_index {
None
} else {
Some(new_index)
}
} }
fn selection_updown( fn selection_updown(
&self, &self,
current_index: usize, current_index: usize,
up: bool, direction: Direction,
) -> Option<usize> { ) -> Option<usize> {
let mut index = current_index; if direction == Direction::Up {
self.get_new_selection(
loop { (0..=current_index.saturating_sub(1)).rev(),
index = { 1,
let new_index = if up { )
index.saturating_sub(1)
} else {
index.saturating_add(1)
};
// when reaching usize bounds
if new_index == index {
break;
}
if new_index >= self.items.len() {
break;
}
new_index
};
if self.is_visible_index(index) {
break;
}
}
if index == current_index {
None
} else { } else {
Some(index) self.get_new_selection(
(current_index + 1)..(self.items.len()),
1,
)
} }
} }
fn select_parent(&self, current_index: usize) -> Option<usize> { fn select_parent(&self, current_index: usize) -> Option<usize> {
let indent = let current_indent =
self.items.tree_items[current_index].info().indent(); self.items.tree_items[current_index].info().indent();
let mut index = current_index; let range = (0..=current_index).rev();
while let Some(selection) = self.selection_updown(index, true) range.filter(|index| self.is_visible_index(*index)).find(
{ |index| {
index = selection; self.items.tree_items[*index].info().indent()
< current_indent
if self.items.tree_items[index].info().indent() < indent { },
break; )
}
}
if index == current_index {
None
} else {
Some(index)
}
} }
fn selection_left( fn selection_left(
@ -340,7 +307,10 @@ impl FileTree {
self.items.expand(current_selection, false); self.items.expand(current_selection, false);
return Some(current_selection); return Some(current_selection);
} }
return self.selection_updown(current_selection, false); return self.selection_updown(
current_selection,
Direction::Down,
);
} }
None None