diff --git a/src/watch.rs b/src/watch.rs index 6259c9df..58144661 100644 --- a/src/watch.rs +++ b/src/watch.rs @@ -95,6 +95,9 @@ fn run_watch( while let Ok(event) = watch_event_receiver.recv() { match event { + WatchEvent::Input(InputEvent::Previous) => { + watch_state.previous_exercise(&mut stdout)? + } WatchEvent::Input(InputEvent::Next) => match watch_state.next_exercise(&mut stdout)? { ExercisesProgress::AllDone => break, ExercisesProgress::NewPending => watch_state.run_current_exercise(&mut stdout)?, diff --git a/src/watch/state.rs b/src/watch/state.rs index 5263bc57..1ab9b36d 100644 --- a/src/watch/state.rs +++ b/src/watch/state.rs @@ -92,12 +92,7 @@ impl<'a> WatchState<'a> { .run_exercise(Some(&mut self.output), self.app_state.cmd_runner())?; self.output.push(b'\n'); if success { - self.done_status = - if let Some(solution_path) = self.app_state.current_solution_path()? { - DoneStatus::DoneWithSolution(solution_path) - } else { - DoneStatus::DoneWithoutSolution - }; + self.done_status = self.completed_exercise_status()?; } else { self.app_state .set_pending(self.app_state.current_exercise_ind())?; @@ -170,6 +165,17 @@ impl<'a> WatchState<'a> { } fn show_prompt(&self, stdout: &mut StdoutLock) -> io::Result<()> { + if self.app_state.current_exercise_ind() != 0 { + stdout.queue(SetAttribute(Attribute::Bold))?; + stdout.write_all(b"p")?; + stdout.queue(ResetColor)?; + stdout.write_all(b":")?; + stdout.queue(SetAttribute(Attribute::Underlined))?; + stdout.write_all(b"previous")?; + stdout.queue(ResetColor)?; + stdout.write_all(b" / ")?; + } + if self.done_status != DoneStatus::Pending { stdout.queue(SetAttribute(Attribute::Bold))?; stdout.write_all(b"n")?; @@ -295,4 +301,31 @@ impl<'a> WatchState<'a> { Ok(()) } + + fn completed_exercise_status(&self) -> Result { + if let Some(solution_path) = self.app_state.current_solution_path()? { + Ok(DoneStatus::DoneWithSolution(solution_path)) + } else { + Ok(DoneStatus::DoneWithoutSolution) + } + } + + pub fn previous_exercise(&mut self, stdout: &mut StdoutLock) -> Result<()> { + let current_exercise_ind = self.app_state.current_exercise_ind(); + + if current_exercise_ind == 0 { + return Ok(()); + } + + self.app_state + .set_current_exercise_ind(current_exercise_ind - 1)?; + self.done_status = if self.app_state.current_exercise().done { + self.completed_exercise_status()? + } else { + DoneStatus::Pending + }; + self.render(stdout)?; + + Ok(()) + } } diff --git a/src/watch/terminal_event.rs b/src/watch/terminal_event.rs index 48411db0..80d4595f 100644 --- a/src/watch/terminal_event.rs +++ b/src/watch/terminal_event.rs @@ -7,6 +7,7 @@ use std::sync::{ use super::{WatchEvent, EXERCISE_RUNNING}; pub enum InputEvent { + Previous, Next, Run, Hint, @@ -34,6 +35,7 @@ pub fn terminal_event_handler( } let input_event = match key.code { + KeyCode::Char('p') => InputEvent::Previous, KeyCode::Char('n') => InputEvent::Next, KeyCode::Char('r') if manual_run => InputEvent::Run, KeyCode::Char('h') => InputEvent::Hint,