summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app_state.rs24
-rw-r--r--src/watch.rs7
-rw-r--r--src/watch/state.rs22
-rw-r--r--src/watch/terminal_event.rs2
4 files changed, 51 insertions, 4 deletions
diff --git a/src/app_state.rs b/src/app_state.rs
index de5a382..99772b7 100644
--- a/src/app_state.rs
+++ b/src/app_state.rs
@@ -396,8 +396,16 @@ impl AppState {
}
// Return the exercise index of the first pending exercise found.
- fn check_all_exercises(&mut self, stdout: &mut StdoutLock) -> Result<Option<usize>> {
- stdout.write_all(FINAL_CHECK_MSG)?;
+ pub fn check_all_exercises(
+ &mut self,
+ stdout: &mut StdoutLock,
+ final_check: bool,
+ ) -> Result<Option<usize>> {
+ if !final_check {
+ stdout.write_all(INTERMEDIATE_CHECK_MSG)?;
+ } else {
+ stdout.write_all(FINAL_CHECK_MSG)?;
+ }
let n_exercises = self.exercises.len();
let (mut checked_count, mut results) = thread::scope(|s| {
@@ -513,7 +521,7 @@ impl AppState {
stdout.write_all(b"\n")?;
}
- if let Some(pending_exercise_ind) = self.check_all_exercises(stdout)? {
+ if let Some(pending_exercise_ind) = self.check_all_exercises(stdout, true)? {
stdout.write_all(b"\n\n")?;
self.current_exercise_ind = pending_exercise_ind;
@@ -525,6 +533,12 @@ impl AppState {
// Write that the last exercise is done.
self.write()?;
+ self.render_final_message(stdout)?;
+
+ Ok(ExercisesProgress::AllDone)
+ }
+
+ pub fn render_final_message(&self, stdout: &mut StdoutLock) -> Result<()> {
clear_terminal(stdout)?;
stdout.write_all(FENISH_LINE.as_bytes())?;
@@ -534,12 +548,14 @@ impl AppState {
stdout.write_all(b"\n")?;
}
- Ok(ExercisesProgress::AllDone)
+ Ok(())
}
}
const BAD_INDEX_ERR: &str = "The current exercise index is higher than the number of exercises";
const STATE_FILE_HEADER: &[u8] = b"DON'T EDIT THIS FILE!\n\n";
+const INTERMEDIATE_CHECK_MSG: &[u8] = b"Checking all exercises
+";
const FINAL_CHECK_MSG: &[u8] = b"All exercises seem to be done.
Recompiling and running all exercises to make sure that all of them are actually done.
";
diff --git a/src/watch.rs b/src/watch.rs
index 35533b0..b984675 100644
--- a/src/watch.rs
+++ b/src/watch.rs
@@ -103,6 +103,13 @@ fn run_watch(
WatchEvent::Input(InputEvent::Run) => watch_state.run_current_exercise(&mut stdout)?,
WatchEvent::Input(InputEvent::Hint) => watch_state.show_hint(&mut stdout)?,
WatchEvent::Input(InputEvent::List) => return Ok(WatchExit::List),
+ WatchEvent::Input(InputEvent::CheckAll) => match watch_state
+ .check_all_exercises(&mut stdout)?
+ {
+ ExercisesProgress::AllDone => break,
+ ExercisesProgress::NewPending => watch_state.run_current_exercise(&mut stdout)?,
+ ExercisesProgress::CurrentPending => (),
+ },
WatchEvent::Input(InputEvent::Reset) => watch_state.reset_exercise(&mut stdout)?,
WatchEvent::Input(InputEvent::Quit) => {
stdout.write_all(QUIT_MSG)?;
diff --git a/src/watch/state.rs b/src/watch/state.rs
index 19910f0..67a6357 100644
--- a/src/watch/state.rs
+++ b/src/watch/state.rs
@@ -196,6 +196,11 @@ impl<'a> WatchState<'a> {
stdout.write_all(b":list / ")?;
stdout.queue(SetAttribute(Attribute::Bold))?;
+ stdout.write_all(b"c")?;
+ stdout.queue(ResetColor)?;
+ stdout.write_all(b":check all / ")?;
+
+ stdout.queue(SetAttribute(Attribute::Bold))?;
stdout.write_all(b"x")?;
stdout.queue(ResetColor)?;
stdout.write_all(b":reset / ")?;
@@ -274,6 +279,23 @@ impl<'a> WatchState<'a> {
Ok(())
}
+ pub fn check_all_exercises(&mut self, stdout: &mut StdoutLock) -> Result<ExercisesProgress> {
+ stdout.write_all(b"\n")?;
+
+ if let Some(first_fail) = self.app_state.check_all_exercises(stdout, false)? {
+ // Only change exercise if the current one is done...
+ if self.app_state.current_exercise().done {
+ self.app_state.set_current_exercise_ind(first_fail)?;
+ }
+ // ...but always pretend it's a "new" anyway because that refreshes
+ // the display
+ Ok(ExercisesProgress::NewPending)
+ } else {
+ self.app_state.render_final_message(stdout)?;
+ Ok(ExercisesProgress::AllDone)
+ }
+ }
+
pub fn update_term_width(&mut self, width: u16, stdout: &mut StdoutLock) -> io::Result<()> {
if self.term_width != width {
self.term_width = width;
diff --git a/src/watch/terminal_event.rs b/src/watch/terminal_event.rs
index 1ed681d..48411db 100644
--- a/src/watch/terminal_event.rs
+++ b/src/watch/terminal_event.rs
@@ -11,6 +11,7 @@ pub enum InputEvent {
Run,
Hint,
List,
+ CheckAll,
Reset,
Quit,
}
@@ -37,6 +38,7 @@ pub fn terminal_event_handler(
KeyCode::Char('r') if manual_run => InputEvent::Run,
KeyCode::Char('h') => InputEvent::Hint,
KeyCode::Char('l') => break WatchEvent::Input(InputEvent::List),
+ KeyCode::Char('c') => InputEvent::CheckAll,
KeyCode::Char('x') => {
if sender.send(WatchEvent::Input(InputEvent::Reset)).is_err() {
return;