From 9c8ca6c7420b1483b1df9dbf373ba3295745eceb Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sun, 5 Dec 2021 18:23:33 -0500 Subject: allow searching backwards --- src/bin/ttyplay/display.rs | 58 ++++++++++++++++++++++++---------------------- src/bin/ttyplay/event.rs | 18 +++++++------- src/bin/ttyplay/frames.rs | 27 ++++++++++++++++----- src/bin/ttyplay/input.rs | 16 ++++++++++++- src/bin/ttyplay/timer.rs | 4 ++-- 5 files changed, 77 insertions(+), 46 deletions(-) diff --git a/src/bin/ttyplay/display.rs b/src/bin/ttyplay/display.rs index 7572936..f8b7e71 100644 --- a/src/bin/ttyplay/display.rs +++ b/src/bin/ttyplay/display.rs @@ -126,34 +126,36 @@ impl Display { output.set_fgcolor(textmode::color::BLACK); output.set_bgcolor(textmode::color::CYAN); - output.move_to(size.0 - 15, size.1 - 27); - output.write_str(" keys "); - output.move_to(size.0 - 14, size.1 - 27); - output.write_str(" q: quit "); - output.move_to(size.0 - 13, size.1 - 27); - output.write_str(" space: pause/unpause "); - output.move_to(size.0 - 12, size.1 - 27); - output.write_str(" tab: hide/show ui "); - output.move_to(size.0 - 11, size.1 - 27); - output.write_str(" h: previous fram "); - output.move_to(size.0 - 10, size.1 - 27); - output.write_str(" l: next frame "); - output.move_to(size.0 - 9, size.1 - 27); - output.write_str(" 0: first frame "); - output.move_to(size.0 - 8, size.1 - 27); - output.write_str(" $: last frame "); - output.move_to(size.0 - 7, size.1 - 27); - output.write_str(" +: increase speed "); - output.move_to(size.0 - 6, size.1 - 27); - output.write_str(" -: decrease speed "); - output.move_to(size.0 - 5, size.1 - 27); - output.write_str(" =: normal speed "); - output.move_to(size.0 - 4, size.1 - 27); - output.write_str(" /: search "); - output.move_to(size.0 - 3, size.1 - 27); - output.write_str(" n: repeat last search "); - output.move_to(size.0 - 2, size.1 - 27); - output.write_str(" ?: hide/show help "); + output.move_to(size.0 - 16, size.1 - 23); + output.write_str(" keys "); + output.move_to(size.0 - 15, size.1 - 23); + output.write_str(" q: quit "); + output.move_to(size.0 - 14, size.1 - 23); + output.write_str(" space: pause/unpause "); + output.move_to(size.0 - 13, size.1 - 23); + output.write_str(" tab: hide/show ui "); + output.move_to(size.0 - 12, size.1 - 23); + output.write_str(" h: previous frame "); + output.move_to(size.0 - 11, size.1 - 23); + output.write_str(" l: next frame "); + output.move_to(size.0 - 10, size.1 - 23); + output.write_str(" 0: first frame "); + output.move_to(size.0 - 9, size.1 - 23); + output.write_str(" $: last frame "); + output.move_to(size.0 - 8, size.1 - 23); + output.write_str(" +: increase speed "); + output.move_to(size.0 - 7, size.1 - 23); + output.write_str(" -: decrease speed "); + output.move_to(size.0 - 6, size.1 - 23); + output.write_str(" =: normal speed "); + output.move_to(size.0 - 5, size.1 - 23); + output.write_str(" /: search "); + output.move_to(size.0 - 4, size.1 - 23); + output.write_str(" n: next match "); + output.move_to(size.0 - 3, size.1 - 23); + output.write_str(" p: previous match "); + output.move_to(size.0 - 2, size.1 - 23); + output.write_str(" ?: hide/show help "); } fn render_search(&self, output: &mut textmode::Output) { diff --git a/src/bin/ttyplay/event.rs b/src/bin/ttyplay/event.rs index de81220..667d43f 100644 --- a/src/bin/ttyplay/event.rs +++ b/src/bin/ttyplay/event.rs @@ -7,7 +7,7 @@ pub enum Event { ToggleHelp, ActiveSearch(String), CancelSearch, - RunSearch(String), + RunSearch(String, bool), Quit, } @@ -20,7 +20,7 @@ pub enum TimerAction { SpeedUp, SlowDown, DefaultSpeed, - Search(String), + Search(String, bool), Quit, } @@ -78,7 +78,7 @@ struct Pending { toggle_help: bool, active_search: Option, cancel_search: bool, - run_search: Option, + run_search: Option<(String, bool)>, quit: bool, } @@ -121,10 +121,10 @@ impl Pending { self.cancel_search = true; self.run_search = None; } - Event::RunSearch(s) => { + Event::RunSearch(s, backwards) => { self.active_search = None; self.cancel_search = false; - self.run_search = Some(s); + self.run_search = Some((s, backwards)); } Event::Quit => { self.quit = true; @@ -157,8 +157,8 @@ impl Pending { } else if self.cancel_search { self.cancel_search = false; Some(Event::CancelSearch) - } else if let Some(run_search) = self.run_search.take() { - Some(Event::RunSearch(run_search)) + } else if let Some((run_search, backwards)) = self.run_search.take() { + Some(Event::RunSearch(run_search, backwards)) } else if self.toggle_ui { self.toggle_ui = false; Some(Event::ToggleUi) @@ -219,9 +219,9 @@ pub async fn handle_events( Event::CancelSearch => { display.clear_search(); } - Event::RunSearch(s) => { + Event::RunSearch(s, backwards) => { display.clear_search(); - timer_w.send(TimerAction::Search(s)).await?; + timer_w.send(TimerAction::Search(s, backwards)).await?; } Event::Quit => { break; diff --git a/src/bin/ttyplay/frames.rs b/src/bin/ttyplay/frames.rs index 0808c58..dd60a21 100644 --- a/src/bin/ttyplay/frames.rs +++ b/src/bin/ttyplay/frames.rs @@ -44,13 +44,28 @@ impl FrameData { self.frames.len() } - pub fn search(&self, start: usize, query: &str) -> Option { - for (idx, frame) in self.frames.iter().enumerate().skip(start) { - if frame.screen.contents().contains(query) { - return Some(idx); - } + pub fn search( + &self, + start: usize, + query: &str, + backwards: bool, + ) -> Option { + if backwards { + self.frames + .iter() + .enumerate() + .rev() + .skip(self.frames.len() - start + 1) + .find(|(_, frame)| frame.screen.contents().contains(query)) + .map(|(i, _)| i) + } else { + self.frames + .iter() + .enumerate() + .skip(start) + .find(|(_, frame)| frame.screen.contents().contains(query)) + .map(|(i, _)| i) } - None } pub async fn add_frame(&mut self, frame: Frame) { diff --git a/src/bin/ttyplay/input.rs b/src/bin/ttyplay/input.rs index e953f6d..f69423b 100644 --- a/src/bin/ttyplay/input.rs +++ b/src/bin/ttyplay/input.rs @@ -30,6 +30,7 @@ pub fn spawn_task( event_w .send(crate::event::Event::RunSearch( search_contents.clone(), + false, )) .await .unwrap(); @@ -100,7 +101,20 @@ pub fn spawn_task( } textmode::Key::Char('n') => { if let Some(ref search) = prev_search { - crate::event::Event::RunSearch(search.clone()) + crate::event::Event::RunSearch( + search.clone(), + false, + ) + } else { + continue; + } + } + textmode::Key::Char('p') => { + if let Some(ref search) = prev_search { + crate::event::Event::RunSearch( + search.clone(), + true, + ) } else { continue; } diff --git a/src/bin/ttyplay/timer.rs b/src/bin/ttyplay/timer.rs index eb60185..62bbff9 100644 --- a/src/bin/ttyplay/timer.rs +++ b/src/bin/ttyplay/timer.rs @@ -138,9 +138,9 @@ pub fn spawn_task( - (((now - start_time) * 16) / playback_ratio); playback_ratio = 16; } - crate::event::TimerAction::Search(s) => { + crate::event::TimerAction::Search(s, backwards) => { if let Some(new_idx) = - frames.lock_arc().await.search(idx + 1, &s) + frames.lock_arc().await.search(idx, &s, backwards) { idx = new_idx; force_update_time = true; -- cgit v1.2.3-54-g00ecf