diff --git a/src/watch.rs b/src/watch.rs
index 11450b4..35533b0 100644
--- a/src/watch.rs
+++ b/src/watch.rs
@@ -100,13 +100,14 @@ fn run_watch(
                 ExercisesProgress::NewPending => watch_state.run_current_exercise(&mut stdout)?,
                 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::List) => return Ok(WatchExit::List),
+            WatchEvent::Input(InputEvent::Reset) => watch_state.reset_exercise(&mut stdout)?,
             WatchEvent::Input(InputEvent::Quit) => {
                 stdout.write_all(QUIT_MSG)?;
                 break;
             }
-            WatchEvent::Input(InputEvent::Run) => watch_state.run_current_exercise(&mut stdout)?,
             WatchEvent::FileChange { exercise_ind } => {
                 watch_state.handle_file_change(exercise_ind, &mut stdout)?;
             }
diff --git a/src/watch/state.rs b/src/watch/state.rs
index d6c3eb2..19910f0 100644
--- a/src/watch/state.rs
+++ b/src/watch/state.rs
@@ -6,8 +6,8 @@ use crossterm::{
     terminal, QueueableCommand,
 };
 use std::{
-    io::{self, StdoutLock, Write},
-    sync::mpsc::Sender,
+    io::{self, Read, StdoutLock, Write},
+    sync::mpsc::{sync_channel, Sender, SyncSender},
     thread,
 };
 
@@ -34,6 +34,7 @@ pub struct WatchState<'a> {
     done_status: DoneStatus,
     manual_run: bool,
     term_width: u16,
+    terminal_event_unpause_sender: SyncSender<()>,
 }
 
 impl<'a> WatchState<'a> {
@@ -46,8 +47,16 @@ impl<'a> WatchState<'a> {
             .context("Failed to get the terminal size")?
             .0;
 
+        let (terminal_event_unpause_sender, terminal_event_unpause_receiver) = sync_channel(0);
+
         thread::Builder::new()
-            .spawn(move || terminal_event_handler(watch_event_sender, manual_run))
+            .spawn(move || {
+                terminal_event_handler(
+                    watch_event_sender,
+                    terminal_event_unpause_receiver,
+                    manual_run,
+                )
+            })
             .context("Failed to spawn a thread to handle terminal events")?;
 
         Ok(Self {
@@ -57,6 +66,7 @@ impl<'a> WatchState<'a> {
             done_status: DoneStatus::Pending,
             manual_run,
             term_width,
+            terminal_event_unpause_sender,
         })
     }
 
@@ -95,6 +105,44 @@ impl<'a> WatchState<'a> {
         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(
         &mut self,
         exercise_ind: usize,
@@ -117,13 +165,6 @@ impl<'a> WatchState<'a> {
     }
 
     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 {
             stdout.queue(SetAttribute(Attribute::Bold))?;
             stdout.write_all(b"n")?;
@@ -135,6 +176,13 @@ impl<'a> WatchState<'a> {
             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 {
             stdout.queue(SetAttribute(Attribute::Bold))?;
             stdout.write_all(b"h")?;
@@ -147,6 +195,11 @@ impl<'a> WatchState<'a> {
         stdout.queue(ResetColor)?;
         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.write_all(b"q")?;
         stdout.queue(ResetColor)?;
diff --git a/src/watch/terminal_event.rs b/src/watch/terminal_event.rs
index 050c4ac..1ed681d 100644
--- a/src/watch/terminal_event.rs
+++ b/src/watch/terminal_event.rs
@@ -1,17 +1,25 @@
 use crossterm::event::{self, Event, KeyCode, KeyEventKind};
-use std::sync::{atomic::Ordering::Relaxed, mpsc::Sender};
+use std::sync::{
+    atomic::Ordering::Relaxed,
+    mpsc::{Receiver, Sender},
+};
 
 use super::{WatchEvent, EXERCISE_RUNNING};
 
 pub enum InputEvent {
-    Run,
     Next,
+    Run,
     Hint,
     List,
+    Reset,
     Quit,
 }
 
-pub fn terminal_event_handler(sender: Sender<WatchEvent>, manual_run: bool) {
+pub fn terminal_event_handler(
+    sender: Sender<WatchEvent>,
+    unpause_receiver: Receiver<()>,
+    manual_run: bool,
+) {
     let last_watch_event = loop {
         match event::read() {
             Ok(Event::Key(key)) => {
@@ -26,10 +34,22 @@ pub fn terminal_event_handler(sender: Sender<WatchEvent>, manual_run: bool) {
 
                 let input_event = match key.code {
                     KeyCode::Char('n') => InputEvent::Next,
+                    KeyCode::Char('r') if manual_run => InputEvent::Run,
                     KeyCode::Char('h') => InputEvent::Hint,
                     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('r') if manual_run => InputEvent::Run,
                     _ => continue,
                 };