Skip to content
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

Fix incorrect highlighting of lists when filtered #110

Merged
merged 1 commit into from Apr 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 7 additions & 10 deletions src/ui/backend.rs
Expand Up @@ -209,9 +209,7 @@ where
) -> Result<()> {
let empty_prefix = Styled::new(" ");

let page_cursor_relative_index = page.cursor.map(|c| c.relative_index);

let x = if page_cursor_relative_index == Some(option_relative_index) {
let x = if page.cursor == Some(option_relative_index) {
self.render_config.highlighted_option_prefix
} else if option_relative_index == 0 && !page.first {
self.render_config.scroll_up_prefix
Expand All @@ -226,12 +224,13 @@ where

fn print_option_value<D: Display>(
&mut self,
option_relative_index: usize,
option: &ListOption<D>,
page: &Page<ListOption<D>>,
) -> Result<()> {
let stylesheet = if let Some(selected_option_style) = self.render_config.selected_option {
match page.cursor {
Some(cursor) if cursor.absolute_index == option.index => selected_option_style,
Some(cursor) if cursor == option_relative_index => selected_option_style,
_ => self.render_config.option,
}
} else {
Expand Down Expand Up @@ -464,7 +463,7 @@ where
self.print_option_prefix(idx, &page)?;

self.terminal.write(" ")?;
self.print_option_value(option, &page)?;
self.print_option_value(idx, option, &page)?;

self.new_line()?;
}
Expand Down Expand Up @@ -512,7 +511,7 @@ where
self.terminal.write(" ")?;
}

self.print_option_value(option, &page)?;
self.print_option_value(idx, option, &page)?;

self.new_line()?;
}
Expand Down Expand Up @@ -550,17 +549,15 @@ where
};

match (self.render_config.selected_option, page.cursor) {
(Some(stylesheet), Some(cursor)) if cursor.absolute_index == option.index => {
checkbox.style = stylesheet
}
(Some(stylesheet), Some(cursor)) if cursor == idx => checkbox.style = stylesheet,
_ => {}
}

self.terminal.write_styled(&checkbox)?;

self.terminal.write(" ")?;

self.print_option_value(option, &page)?;
self.print_option_value(idx, option, &page)?;

self.new_line()?;
}
Expand Down
53 changes: 20 additions & 33 deletions src/utils.rs
Expand Up @@ -2,17 +2,20 @@

use std::fmt::Debug;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Cursor {
pub relative_index: usize,
pub absolute_index: usize,
}

pub struct Page<'a, T> {
/// Whether this is the first page.
pub first: bool,

/// Whether this is the last page.
pub last: bool,

/// Content of the page.
pub content: &'a [T],
pub cursor: Option<Cursor>,

/// If a cursor exists on the original list, this is the index of the new cursor relative to the output list of choices, the page.
pub cursor: Option<usize>,

/// Total amount of elements in the original list of choices.
pub total: usize,
}

Expand All @@ -21,20 +24,20 @@ pub fn paginate<T>(page_size: usize, choices: &[T], sel: Option<usize>) -> Page<
// in practice, the same as selecting the 0 index.

let (start, end, cursor) = if choices.len() <= page_size {
(0, choices.len(), sel.map(Cursor::same))
(0, choices.len(), sel)
} else if let Some(index) = sel {
if index < page_size / 2 {
// if we are in the first half page
let start = 0;
let end = page_size;
let cursor = Some(Cursor::same(index));
let cursor = Some(index);

(start, end, cursor)
} else if choices.len() - index - 1 < page_size / 2 {
// if we are in the last half page
let start = choices.len() - page_size;
let end = choices.len();
let cursor = Some(Cursor::new(index - start, index));
let cursor = Some(index - start);

(start, end, cursor)
} else {
Expand All @@ -44,7 +47,7 @@ pub fn paginate<T>(page_size: usize, choices: &[T], sel: Option<usize>) -> Page<

let start = index - above;
let end = index + below;
let cursor = Some(Cursor::new(page_size / 2, index));
let cursor = Some(page_size / 2);

(start, end, cursor)
}
Expand All @@ -53,7 +56,7 @@ pub fn paginate<T>(page_size: usize, choices: &[T], sel: Option<usize>) -> Page<
let start = 0;
let end = page_size;

(start, end, sel.map(Cursor::same))
(start, end, sel)
};

Page {
Expand All @@ -65,22 +68,6 @@ pub fn paginate<T>(page_size: usize, choices: &[T], sel: Option<usize>) -> Page<
}
}

impl Cursor {
fn new(relative_index: usize, absolute_index: usize) -> Cursor {
Cursor {
relative_index,
absolute_index,
}
}

fn same(idx: usize) -> Cursor {
Cursor {
relative_index: idx,
absolute_index: idx,
}
}
}

pub fn int_log10<T>(mut i: T) -> usize
where
T: std::ops::DivAssign + std::cmp::PartialOrd + From<u8> + Copy,
Expand All @@ -103,7 +90,7 @@ mod test {

use crate::{
list_option::ListOption,
utils::{int_log10, paginate, Cursor},
utils::{int_log10, paginate},
};

#[test]
Expand Down Expand Up @@ -135,7 +122,7 @@ mod test {
let page = paginate(page_size, &choices, sel);

assert_eq!(choices[..], page.content[..]);
assert_eq!(Some(Cursor::new(3usize, 3)), page.cursor);
assert_eq!(Some(3usize), page.cursor);
assert_eq!(true, page.first);
assert_eq!(true, page.last);
assert_eq!(3, page.total);
Expand Down Expand Up @@ -167,7 +154,7 @@ mod test {
let page = paginate(page_size, &choices, sel);

assert_eq!(choices[0..4], page.content[..]);
assert_eq!(Some(Cursor::new(2, 2)), page.cursor);
assert_eq!(Some(2), page.cursor);
assert_eq!(true, page.first);
assert_eq!(false, page.last);
assert_eq!(6, page.total);
Expand Down Expand Up @@ -199,7 +186,7 @@ mod test {
let page = paginate(page_size, &choices, sel);

assert_eq!(choices[2..4], page.content[..]);
assert_eq!(Some(Cursor::new(1, 3)), page.cursor);
assert_eq!(Some(1), page.cursor);
assert_eq!(false, page.first);
assert_eq!(false, page.last);
assert_eq!(6, page.total);
Expand Down Expand Up @@ -231,7 +218,7 @@ mod test {
let page = paginate(page_size, &choices, sel);

assert_eq!(choices[3..6], page.content[..]);
assert_eq!(Some(Cursor::new(2, 5)), page.cursor);
assert_eq!(Some(2), page.cursor);
assert_eq!(false, page.first);
assert_eq!(true, page.last);
assert_eq!(6, page.total);
Expand Down