Compare commits

..

No commits in common. "0c79f2ea3e1fd2db54ebe8fba8ed17369a15b365" and "0d258b9e9691468fd1c9a46378446467a14be765" have entirely different histories.

4 changed files with 16 additions and 90 deletions

View file

@ -1144,7 +1144,7 @@ constants, but clippy recognizes those imprecise mathematical constants as a
source of potential error. source of potential error.
See the suggestions of the Clippy warning in the compile output and use the See the suggestions of the Clippy warning in the compile output and use the
appropriate replacement constant from `std::f32::consts`.""" appropriate replacement constant from `std::f32::consts`..."""
[[exercises]] [[exercises]]
name = "clippy2" name = "clippy2"

View file

@ -100,14 +100,13 @@ fn run_watch(
ExercisesProgress::NewPending => watch_state.run_current_exercise(&mut stdout)?, ExercisesProgress::NewPending => watch_state.run_current_exercise(&mut stdout)?,
ExercisesProgress::CurrentPending => (), ExercisesProgress::CurrentPending => (),
}, },
WatchEvent::Input(InputEvent::Run) => watch_state.run_current_exercise(&mut stdout)?,
WatchEvent::Input(InputEvent::Hint) => watch_state.show_hint(&mut stdout)?, WatchEvent::Input(InputEvent::Hint) => watch_state.show_hint(&mut stdout)?,
WatchEvent::Input(InputEvent::List) => return Ok(WatchExit::List), WatchEvent::Input(InputEvent::List) => return Ok(WatchExit::List),
WatchEvent::Input(InputEvent::Reset) => watch_state.reset_exercise(&mut stdout)?,
WatchEvent::Input(InputEvent::Quit) => { WatchEvent::Input(InputEvent::Quit) => {
stdout.write_all(QUIT_MSG)?; stdout.write_all(QUIT_MSG)?;
break; break;
} }
WatchEvent::Input(InputEvent::Run) => watch_state.run_current_exercise(&mut stdout)?,
WatchEvent::FileChange { exercise_ind } => { WatchEvent::FileChange { exercise_ind } => {
watch_state.handle_file_change(exercise_ind, &mut stdout)?; watch_state.handle_file_change(exercise_ind, &mut stdout)?;
} }

View file

@ -6,8 +6,8 @@ use crossterm::{
terminal, QueueableCommand, terminal, QueueableCommand,
}; };
use std::{ use std::{
io::{self, Read, StdoutLock, Write}, io::{self, StdoutLock, Write},
sync::mpsc::{sync_channel, Sender, SyncSender}, sync::mpsc::Sender,
thread, thread,
}; };
@ -34,7 +34,6 @@ pub struct WatchState<'a> {
done_status: DoneStatus, done_status: DoneStatus,
manual_run: bool, manual_run: bool,
term_width: u16, term_width: u16,
terminal_event_unpause_sender: SyncSender<()>,
} }
impl<'a> WatchState<'a> { impl<'a> WatchState<'a> {
@ -47,16 +46,8 @@ impl<'a> WatchState<'a> {
.context("Failed to get the terminal size")? .context("Failed to get the terminal size")?
.0; .0;
let (terminal_event_unpause_sender, terminal_event_unpause_receiver) = sync_channel(0);
thread::Builder::new() thread::Builder::new()
.spawn(move || { .spawn(move || terminal_event_handler(watch_event_sender, manual_run))
terminal_event_handler(
watch_event_sender,
terminal_event_unpause_receiver,
manual_run,
)
})
.context("Failed to spawn a thread to handle terminal events")?; .context("Failed to spawn a thread to handle terminal events")?;
Ok(Self { Ok(Self {
@ -66,7 +57,6 @@ impl<'a> WatchState<'a> {
done_status: DoneStatus::Pending, done_status: DoneStatus::Pending,
manual_run, manual_run,
term_width, term_width,
terminal_event_unpause_sender,
}) })
} }
@ -105,44 +95,6 @@ impl<'a> WatchState<'a> {
Ok(()) Ok(())
} }
pub fn reset_exercise(&mut self, stdout: &mut StdoutLock) -> Result<()> {
clear_terminal(stdout)?;
stdout.write_all(b"Resetting will undo all your changes to the file ")?;
stdout.write_all(self.app_state.current_exercise().path.as_bytes())?;
stdout.write_all(b"\nReset (y/n)? ")?;
stdout.flush()?;
{
let mut stdin = io::stdin().lock();
let mut answer = [0];
loop {
stdin
.read_exact(&mut answer)
.context("Failed to read the user's input")?;
match answer[0] {
b'y' | b'Y' => {
self.app_state.reset_current_exercise()?;
// The file watcher reruns the exercise otherwise.
if self.manual_run {
self.run_current_exercise(stdout)?;
}
}
b'n' | b'N' => self.render(stdout)?,
_ => continue,
}
break;
}
}
self.terminal_event_unpause_sender.send(())?;
Ok(())
}
pub fn handle_file_change( pub fn handle_file_change(
&mut self, &mut self,
exercise_ind: usize, exercise_ind: usize,
@ -165,6 +117,13 @@ impl<'a> WatchState<'a> {
} }
fn show_prompt(&self, stdout: &mut StdoutLock) -> io::Result<()> { fn show_prompt(&self, stdout: &mut StdoutLock) -> io::Result<()> {
if self.manual_run {
stdout.queue(SetAttribute(Attribute::Bold))?;
stdout.write_all(b"r")?;
stdout.queue(ResetColor)?;
stdout.write_all(b":run / ")?;
}
if self.done_status != DoneStatus::Pending { if self.done_status != DoneStatus::Pending {
stdout.queue(SetAttribute(Attribute::Bold))?; stdout.queue(SetAttribute(Attribute::Bold))?;
stdout.write_all(b"n")?; stdout.write_all(b"n")?;
@ -176,13 +135,6 @@ impl<'a> WatchState<'a> {
stdout.write_all(b" / ")?; stdout.write_all(b" / ")?;
} }
if self.manual_run {
stdout.queue(SetAttribute(Attribute::Bold))?;
stdout.write_all(b"r")?;
stdout.queue(ResetColor)?;
stdout.write_all(b":run / ")?;
}
if !self.show_hint { if !self.show_hint {
stdout.queue(SetAttribute(Attribute::Bold))?; stdout.queue(SetAttribute(Attribute::Bold))?;
stdout.write_all(b"h")?; stdout.write_all(b"h")?;
@ -195,11 +147,6 @@ impl<'a> WatchState<'a> {
stdout.queue(ResetColor)?; stdout.queue(ResetColor)?;
stdout.write_all(b":list / ")?; stdout.write_all(b":list / ")?;
stdout.queue(SetAttribute(Attribute::Bold))?;
stdout.write_all(b"x")?;
stdout.queue(ResetColor)?;
stdout.write_all(b":reset / ")?;
stdout.queue(SetAttribute(Attribute::Bold))?; stdout.queue(SetAttribute(Attribute::Bold))?;
stdout.write_all(b"q")?; stdout.write_all(b"q")?;
stdout.queue(ResetColor)?; stdout.queue(ResetColor)?;

View file

@ -1,25 +1,17 @@
use crossterm::event::{self, Event, KeyCode, KeyEventKind}; use crossterm::event::{self, Event, KeyCode, KeyEventKind};
use std::sync::{ use std::sync::{atomic::Ordering::Relaxed, mpsc::Sender};
atomic::Ordering::Relaxed,
mpsc::{Receiver, Sender},
};
use super::{WatchEvent, EXERCISE_RUNNING}; use super::{WatchEvent, EXERCISE_RUNNING};
pub enum InputEvent { pub enum InputEvent {
Next,
Run, Run,
Next,
Hint, Hint,
List, List,
Reset,
Quit, Quit,
} }
pub fn terminal_event_handler( pub fn terminal_event_handler(sender: Sender<WatchEvent>, manual_run: bool) {
sender: Sender<WatchEvent>,
unpause_receiver: Receiver<()>,
manual_run: bool,
) {
let last_watch_event = loop { let last_watch_event = loop {
match event::read() { match event::read() {
Ok(Event::Key(key)) => { Ok(Event::Key(key)) => {
@ -34,22 +26,10 @@ pub fn terminal_event_handler(
let input_event = match key.code { let input_event = match key.code {
KeyCode::Char('n') => InputEvent::Next, KeyCode::Char('n') => InputEvent::Next,
KeyCode::Char('r') if manual_run => InputEvent::Run,
KeyCode::Char('h') => InputEvent::Hint, KeyCode::Char('h') => InputEvent::Hint,
KeyCode::Char('l') => break WatchEvent::Input(InputEvent::List), KeyCode::Char('l') => break WatchEvent::Input(InputEvent::List),
KeyCode::Char('x') => {
if sender.send(WatchEvent::Input(InputEvent::Reset)).is_err() {
return;
}
// Pause input until quitting the confirmation prompt.
if unpause_receiver.recv().is_err() {
return;
};
continue;
}
KeyCode::Char('q') => break WatchEvent::Input(InputEvent::Quit), KeyCode::Char('q') => break WatchEvent::Input(InputEvent::Quit),
KeyCode::Char('r') if manual_run => InputEvent::Run,
_ => continue, _ => continue,
}; };