Skip to content

Simplify (hopefully) code for moving selection in filetreelist #2645

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 61 additions & 91 deletions filetreelist/src/filetree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -116,40 +122,46 @@ 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,
)
}
}

///
pub fn move_selection(&mut self, dir: MoveSelection) -> bool {
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,
),
};

Expand Down Expand Up @@ -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;

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);
}
self.get_new_selection((0..=items_max).rev(), 1)
}

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;

while let Some(selection) = self.selection_updown(index, true)
{
index = selection;
let range = (0..=current_index).rev();

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(
Expand Down Expand Up @@ -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
Expand Down
Loading