Skip to content

Commit c52867e

Browse files
committed
Add command to check all the exercises
This allows for skipping repeating "next" when multiple exercises are done at once, or when earlier exercises have been updated/changed (and thus must be redone) while still working of the whole set (i.e. the final check_all is not yet available to flag those undone exercises)
1 parent 26fd97a commit c52867e

File tree

4 files changed

+51
-4
lines changed

4 files changed

+51
-4
lines changed

src/app_state.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,16 @@ impl AppState {
396396
}
397397

398398
// Return the exercise index of the first pending exercise found.
399-
fn check_all_exercises(&mut self, stdout: &mut StdoutLock) -> Result<Option<usize>> {
400-
stdout.write_all(FINAL_CHECK_MSG)?;
399+
pub fn check_all_exercises(
400+
&mut self,
401+
stdout: &mut StdoutLock,
402+
final_check: bool,
403+
) -> Result<Option<usize>> {
404+
if !final_check {
405+
stdout.write_all(INTERMEDIATE_CHECK_MSG)?;
406+
} else {
407+
stdout.write_all(FINAL_CHECK_MSG)?;
408+
}
401409
let n_exercises = self.exercises.len();
402410

403411
let (mut checked_count, mut results) = thread::scope(|s| {
@@ -513,7 +521,7 @@ impl AppState {
513521
stdout.write_all(b"\n")?;
514522
}
515523

516-
if let Some(pending_exercise_ind) = self.check_all_exercises(stdout)? {
524+
if let Some(pending_exercise_ind) = self.check_all_exercises(stdout, true)? {
517525
stdout.write_all(b"\n\n")?;
518526

519527
self.current_exercise_ind = pending_exercise_ind;
@@ -525,6 +533,12 @@ impl AppState {
525533
// Write that the last exercise is done.
526534
self.write()?;
527535

536+
self.render_final_message(stdout)?;
537+
538+
Ok(ExercisesProgress::AllDone)
539+
}
540+
541+
pub fn render_final_message(&self, stdout: &mut StdoutLock) -> Result<()> {
528542
clear_terminal(stdout)?;
529543
stdout.write_all(FENISH_LINE.as_bytes())?;
530544

@@ -534,12 +548,14 @@ impl AppState {
534548
stdout.write_all(b"\n")?;
535549
}
536550

537-
Ok(ExercisesProgress::AllDone)
551+
Ok(())
538552
}
539553
}
540554

541555
const BAD_INDEX_ERR: &str = "The current exercise index is higher than the number of exercises";
542556
const STATE_FILE_HEADER: &[u8] = b"DON'T EDIT THIS FILE!\n\n";
557+
const INTERMEDIATE_CHECK_MSG: &[u8] = b"Checking all exercises
558+
";
543559
const FINAL_CHECK_MSG: &[u8] = b"All exercises seem to be done.
544560
Recompiling and running all exercises to make sure that all of them are actually done.
545561
";

src/watch.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ fn run_watch(
103103
WatchEvent::Input(InputEvent::Run) => watch_state.run_current_exercise(&mut stdout)?,
104104
WatchEvent::Input(InputEvent::Hint) => watch_state.show_hint(&mut stdout)?,
105105
WatchEvent::Input(InputEvent::List) => return Ok(WatchExit::List),
106+
WatchEvent::Input(InputEvent::CheckAll) => match watch_state
107+
.check_all_exercises(&mut stdout)?
108+
{
109+
ExercisesProgress::AllDone => break,
110+
ExercisesProgress::NewPending => watch_state.run_current_exercise(&mut stdout)?,
111+
ExercisesProgress::CurrentPending => (),
112+
},
106113
WatchEvent::Input(InputEvent::Reset) => watch_state.reset_exercise(&mut stdout)?,
107114
WatchEvent::Input(InputEvent::Quit) => {
108115
stdout.write_all(QUIT_MSG)?;

src/watch/state.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,11 @@ impl<'a> WatchState<'a> {
195195
stdout.queue(ResetColor)?;
196196
stdout.write_all(b":list / ")?;
197197

198+
stdout.queue(SetAttribute(Attribute::Bold))?;
199+
stdout.write_all(b"c")?;
200+
stdout.queue(ResetColor)?;
201+
stdout.write_all(b":check all / ")?;
202+
198203
stdout.queue(SetAttribute(Attribute::Bold))?;
199204
stdout.write_all(b"x")?;
200205
stdout.queue(ResetColor)?;
@@ -274,6 +279,23 @@ impl<'a> WatchState<'a> {
274279
Ok(())
275280
}
276281

282+
pub fn check_all_exercises(&mut self, stdout: &mut StdoutLock) -> Result<ExercisesProgress> {
283+
stdout.write_all(b"\n")?;
284+
285+
if let Some(first_fail) = self.app_state.check_all_exercises(stdout, false)? {
286+
// Only change exercise if the current one is done...
287+
if self.app_state.current_exercise().done {
288+
self.app_state.set_current_exercise_ind(first_fail)?;
289+
}
290+
// ...but always pretend it's a "new" anyway because that refreshes
291+
// the display
292+
Ok(ExercisesProgress::NewPending)
293+
} else {
294+
self.app_state.render_final_message(stdout)?;
295+
Ok(ExercisesProgress::AllDone)
296+
}
297+
}
298+
277299
pub fn update_term_width(&mut self, width: u16, stdout: &mut StdoutLock) -> io::Result<()> {
278300
if self.term_width != width {
279301
self.term_width = width;

src/watch/terminal_event.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub enum InputEvent {
1111
Run,
1212
Hint,
1313
List,
14+
CheckAll,
1415
Reset,
1516
Quit,
1617
}
@@ -37,6 +38,7 @@ pub fn terminal_event_handler(
3738
KeyCode::Char('r') if manual_run => InputEvent::Run,
3839
KeyCode::Char('h') => InputEvent::Hint,
3940
KeyCode::Char('l') => break WatchEvent::Input(InputEvent::List),
41+
KeyCode::Char('c') => InputEvent::CheckAll,
4042
KeyCode::Char('x') => {
4143
if sender.send(WatchEvent::Input(InputEvent::Reset)).is_err() {
4244
return;

0 commit comments

Comments
 (0)