mirror of
https://github.com/gitui-org/gitui
synced 2026-05-23 00:48:35 +00:00
Simplify code for moving selection (#2645)
This commit is contained in:
parent
534da90b12
commit
3b22a4f3b9
1 changed files with 61 additions and 91 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue