From 488d20273e380e88d618613c8a0a736b64373917 Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Mon, 12 Feb 2024 22:52:18 +0100 Subject: [PATCH] Add search_next --- src/tui/app/app.rs | 12 ++++++++++-- src/tui/app/selection.rs | 15 ++++++++++++--- src/tui/handler.rs | 10 ++++++++++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/tui/app/app.rs b/src/tui/app/app.rs index ddf2c6d..e0223da 100644 --- a/src/tui/app/app.rs +++ b/src/tui/app/app.rs @@ -108,6 +108,7 @@ pub trait IAppInteractReload { pub trait IAppInteractSearch { fn append_character(&mut self, ch: char); + fn search_next(&mut self); fn remove_character(&mut self); fn finish_search(&mut self); } @@ -246,6 +247,7 @@ impl IAppInteractBrowse for App { fn begin_search(&mut self) { assert!(self.state.is_browse()); self.state = AppState::Search(String::new()); + // FIXME: this should be the entire selection - not just the artist. self.memo = vec![self.selection.selected_artist()]; self.selection .reset_artist(self.music_hoard.get_collection()); @@ -296,7 +298,6 @@ impl IAppInteractReloadPrivate for App { } } -// FIXME: add `search_next` to find next match // FIXME: once `search_next` is added, backspace should step back. If the previous action was // `search_next` then no character should be removed. If the previous action was to append // a character, a character should be removed. When in doubt see how Emacs's isearch works. @@ -306,7 +307,14 @@ impl IAppInteractSearch for App { let collection = self.music_hoard.get_collection(); let search = self.state.as_mut().unwrap_search(); search.push(ch); - let prev = self.selection.incremental_artist_search(collection, search); + let prev = self.selection.incremental_artist_search(collection, search, false); + self.memo.push(prev); + } + + fn search_next(&mut self) { + let collection = self.music_hoard.get_collection(); + let search = self.state.as_mut().unwrap_search(); + let prev = self.selection.incremental_artist_search(collection, search, true); self.memo.push(prev); } diff --git a/src/tui/app/selection.rs b/src/tui/app/selection.rs index 9316432..be5136c 100644 --- a/src/tui/app/selection.rs +++ b/src/tui/app/selection.rs @@ -108,8 +108,9 @@ impl Selection { &mut self, collection: &Collection, artist_name: &str, + next: bool, ) -> Option { - self.artist.incremental_search(collection, artist_name) + self.artist.incremental_search(collection, artist_name, next) } pub fn increment_selection(&mut self, collection: &Collection, delta: Delta) { @@ -265,14 +266,22 @@ impl ArtistSelection { result } - fn incremental_search(&mut self, artists: &[Artist], artist_name: &str) -> Option { + fn incremental_search( + &mut self, + artists: &[Artist], + artist_name: &str, + next: bool, + ) -> Option { let previous = self.state.list.selected(); - if let Some(index) = self.state.list.selected() { + if let Some(mut index) = self.state.list.selected() { let case_sensitive = Self::is_case_sensitive(artist_name); let char_sensitive = Self::is_char_sensitive(artist_name); let search = Self::normalize_search(artist_name, !case_sensitive, !char_sensitive); + if next && ((index + 1) < artists.len()) { + index += 1; + } let slice = &artists[index..]; let result = slice.iter().position(|probe| { diff --git a/src/tui/handler.rs b/src/tui/handler.rs index 8860ad3..687baf2 100644 --- a/src/tui/handler.rs +++ b/src/tui/handler.rs @@ -146,6 +146,16 @@ impl IEventHandlerPrivate for EventHandler { } fn handle_search_key_event(app: &mut ::SS, key_event: KeyEvent) { + if key_event.modifiers == KeyModifiers::CONTROL { + match key_event.code { + KeyCode::Char('s') | KeyCode::Char('S') => { + app.search_next(); + }, + _ => {} + } + return; + } + match key_event.code { // Add/remove character to search. KeyCode::Char(ch) => app.append_character(ch),