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,
}
#[derive(Clone, Copy, PartialEq)]
enum Direction {
Up,
Down,
}
#[derive(Debug, Clone, Copy)]
pub struct VisualSelection {
pub count: usize,
@ -116,14 +122,22 @@ impl FileTree {
fn selection_page_updown(
&self,
range: impl Iterator<Item = usize>,
current_index: usize,
direction: Direction,
) -> Option<usize> {
let page_size = self.window_height.get().unwrap_or(0);
range
.filter(|index| self.is_visible_index(*index))
.take(page_size)
.last()
if direction == Direction::Up {
self.get_new_selection(
(0..=current_index).rev(),
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| {
let new_index = match dir {
MoveSelection::Up => {
self.selection_updown(selection, true)
self.selection_updown(selection, Direction::Up)
}
MoveSelection::Down => {
self.selection_updown(selection, false)
self.selection_updown(selection, Direction::Down)
}
MoveSelection::Left => self.selection_left(selection),
MoveSelection::Right => {
self.selection_right(selection)
}
MoveSelection::Top => {
Self::selection_start(selection)
}
MoveSelection::End => self.selection_end(selection),
MoveSelection::PageUp => {
self.selection_page_updown((0..=selection).rev())
}
MoveSelection::Top => Some(0),
MoveSelection::End => self.selection_end(),
MoveSelection::PageUp => self
.selection_page_updown(selection, Direction::Up),
MoveSelection::PageDown => self
.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> {
if current_index == 0 {
None
} else {
Some(0)
}
}
fn selection_end(&self, current_index: usize) -> Option<usize> {
fn selection_end(&self) -> Option<usize> {
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 {
if self.is_visible_index(new_index) {
break;
}
if new_index == 0 {
break;
}
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 get_new_selection(
&self,
range: impl Iterator<Item = usize>,
take: usize,
) -> Option<usize> {
range
.filter(|index| self.is_visible_index(*index))
.take(take)
.last()
}
fn selection_updown(
&self,
current_index: usize,
up: bool,
direction: Direction,
) -> Option<usize> {
let mut index = current_index;
loop {
index = {
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
if direction == Direction::Up {
self.get_new_selection(
(0..=current_index.saturating_sub(1)).rev(),
1,
)
} else {
Some(index)
self.get_new_selection(
(current_index + 1)..(self.items.len()),
1,
)
}
}
fn select_parent(&self, current_index: usize) -> Option<usize> {
let indent =
let current_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)
{
index = selection;
if self.items.tree_items[index].info().indent() < indent {
break;
}
}
if index == current_index {
None
} else {
Some(index)
}
range.filter(|index| self.is_visible_index(*index)).find(
|index| {
self.items.tree_items[*index].info().indent()
< current_indent
},
)
}
fn selection_left(
@ -340,7 +307,10 @@ impl FileTree {
self.items.expand(current_selection, false);
return Some(current_selection);
}
return self.selection_updown(current_selection, false);
return self.selection_updown(
current_selection,
Direction::Down,
);
}
None