mirror of
https://github.com/gitui-org/gitui
synced 2026-05-24 09:28:21 +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,
|
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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue