Fix movement keys in inverted mode (#1035)

* Extract scrolling code into functions

* Fix movement keys when inverted

* remove extra len param

---------

Co-authored-by: Conrad Ludgate <conrad.ludgate@truelayer.com>
This commit is contained in:
Jan Larres 2023-06-09 00:28:17 +12:00 committed by GitHub
parent 49f0def12b
commit a224a8e4d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -42,6 +42,7 @@ struct State {
results_state: ListState, results_state: ListState,
switched_search_mode: bool, switched_search_mode: bool,
search_mode: SearchMode, search_mode: SearchMode,
results_len: usize,
search: SearchState, search: SearchState,
engine: Box<dyn SearchEngine>, engine: Box<dyn SearchEngine>,
@ -58,27 +59,26 @@ impl State {
async fn query_results(&mut self, db: &mut dyn Database) -> Result<Vec<History>> { async fn query_results(&mut self, db: &mut dyn Database) -> Result<Vec<History>> {
let results = self.engine.query(&self.search, db).await?; let results = self.engine.query(&self.search, db).await?;
self.results_state.select(0); self.results_state.select(0);
self.results_len = results.len();
Ok(results) Ok(results)
} }
fn handle_input(&mut self, settings: &Settings, input: &Event, len: usize) -> Option<usize> { fn handle_input(&mut self, settings: &Settings, input: &Event) -> Option<usize> {
match input { match input {
Event::Key(k) => self.handle_key_input(settings, k, len), Event::Key(k) => self.handle_key_input(settings, k),
Event::Mouse(m) => self.handle_mouse_input(*m, len), Event::Mouse(m) => self.handle_mouse_input(*m),
Event::Paste(d) => self.handle_paste_input(d), Event::Paste(d) => self.handle_paste_input(d),
_ => None, _ => None,
} }
} }
fn handle_mouse_input(&mut self, input: MouseEvent, len: usize) -> Option<usize> { fn handle_mouse_input(&mut self, input: MouseEvent) -> Option<usize> {
match input.kind { match input.kind {
event::MouseEventKind::ScrollDown => { event::MouseEventKind::ScrollDown => {
let i = self.results_state.selected().saturating_sub(1); self.scroll_down(1);
self.results_state.select(i);
} }
event::MouseEventKind::ScrollUp => { event::MouseEventKind::ScrollUp => {
let i = self.results_state.selected() + 1; self.scroll_up(1);
self.results_state.select(i.min(len - 1));
} }
_ => {} _ => {}
} }
@ -94,12 +94,7 @@ impl State {
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
#[allow(clippy::cognitive_complexity)] #[allow(clippy::cognitive_complexity)]
fn handle_key_input( fn handle_key_input(&mut self, settings: &Settings, input: &KeyEvent) -> Option<usize> {
&mut self,
settings: &Settings,
input: &KeyEvent,
len: usize,
) -> Option<usize> {
if input.kind == event::KeyEventKind::Release { if input.kind == event::KeyEventKind::Release {
return None; return None;
} }
@ -211,39 +206,45 @@ impl State {
}) })
} }
KeyCode::Down if !settings.invert => { KeyCode::Down if !settings.invert => {
let i = self.results_state.selected().saturating_sub(1); self.scroll_down(1);
self.results_state.select(i);
} }
KeyCode::Up if settings.invert => { KeyCode::Up if settings.invert => {
let i = self.results_state.selected().saturating_sub(1); self.scroll_down(1);
self.results_state.select(i);
} }
KeyCode::Char('n' | 'j') if ctrl => { KeyCode::Char('n' | 'j') if ctrl && !settings.invert => {
let i = self.results_state.selected().saturating_sub(1); self.scroll_down(1);
self.results_state.select(i); }
KeyCode::Char('n' | 'j') if ctrl && settings.invert => {
self.scroll_up(1);
} }
KeyCode::Up if !settings.invert => { KeyCode::Up if !settings.invert => {
let i = self.results_state.selected() + 1; self.scroll_up(1);
self.results_state.select(i.min(len - 1));
} }
KeyCode::Down if settings.invert => { KeyCode::Down if settings.invert => {
let i = self.results_state.selected() + 1; self.scroll_up(1);
self.results_state.select(i.min(len - 1));
} }
KeyCode::Char('p' | 'k') if ctrl => { KeyCode::Char('p' | 'k') if ctrl && !settings.invert => {
let i = self.results_state.selected() + 1; self.scroll_up(1);
self.results_state.select(i.min(len - 1)); }
KeyCode::Char('p' | 'k') if ctrl && settings.invert => {
self.scroll_down(1);
} }
KeyCode::Char(c) => self.search.input.insert(c), KeyCode::Char(c) => self.search.input.insert(c),
KeyCode::PageDown => { KeyCode::PageDown if !settings.invert => {
let scroll_len = self.results_state.max_entries() - settings.scroll_context_lines; let scroll_len = self.results_state.max_entries() - settings.scroll_context_lines;
let i = self.results_state.selected().saturating_sub(scroll_len); self.scroll_down(scroll_len);
self.results_state.select(i);
} }
KeyCode::PageUp => { KeyCode::PageDown if settings.invert => {
let scroll_len = self.results_state.max_entries() - settings.scroll_context_lines; let scroll_len = self.results_state.max_entries() - settings.scroll_context_lines;
let i = self.results_state.selected() + scroll_len; self.scroll_up(scroll_len);
self.results_state.select(i.min(len - 1)); }
KeyCode::PageUp if !settings.invert => {
let scroll_len = self.results_state.max_entries() - settings.scroll_context_lines;
self.scroll_up(scroll_len);
}
KeyCode::PageUp if settings.invert => {
let scroll_len = self.results_state.max_entries() - settings.scroll_context_lines;
self.scroll_down(scroll_len);
} }
_ => {} _ => {}
}; };
@ -251,6 +252,16 @@ impl State {
None None
} }
fn scroll_down(&mut self, scroll_len: usize) {
let i = self.results_state.selected().saturating_sub(scroll_len);
self.results_state.select(i);
}
fn scroll_up(&mut self, scroll_len: usize) {
let i = self.results_state.selected() + scroll_len;
self.results_state.select(i.min(self.results_len - 1));
}
#[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_possible_truncation)]
#[allow(clippy::bool_to_int_with_if)] #[allow(clippy::bool_to_int_with_if)]
fn draw<T: Backend>(&mut self, f: &mut Frame<'_, T>, results: &[History], settings: &Settings) { fn draw<T: Backend>(&mut self, f: &mut Frame<'_, T>, results: &[History], settings: &Settings) {
@ -579,6 +590,7 @@ pub async fn history(
}, },
}, },
engine: engines::engine(settings.search_mode), engine: engines::engine(settings.search_mode),
results_len: 0,
}; };
let mut results = app.query_results(&mut db).await?; let mut results = app.query_results(&mut db).await?;
@ -596,7 +608,7 @@ pub async fn history(
event_ready = event_ready => { event_ready = event_ready => {
if event_ready?? { if event_ready?? {
loop { loop {
if let Some(i) = app.handle_input(settings, &event::read()?, results.len()) { if let Some(i) = app.handle_input(settings, &event::read()?) {
break 'render i; break 'render i;
} }
if !event::poll(Duration::ZERO)? { if !event::poll(Duration::ZERO)? {