@@ -11,7 +11,10 @@ use std::{
1111 time:: Duration ,
1212} ;
1313
14- use crate :: app_state:: { AppState , ExercisesProgress } ;
14+ use crate :: {
15+ app_state:: { AppState , ExercisesProgress } ,
16+ list,
17+ } ;
1518
1619use self :: {
1720 notify_event:: NotifyEventHandler ,
@@ -33,15 +36,14 @@ enum WatchEvent {
3336
3437/// Returned by the watch mode to indicate what to do afterwards.
3538#[ must_use]
36- pub enum WatchExit {
39+ enum WatchExit {
3740 /// Exit the program.
3841 Shutdown ,
3942 /// Enter the list mode and restart the watch mode afterwards.
4043 List ,
4144}
4245
43- /// `notify_exercise_names` as None activates the manual run mode.
44- pub fn watch (
46+ fn run_watch (
4547 app_state : & mut AppState ,
4648 notify_exercise_names : Option < & ' static [ & ' static [ u8 ] ] > ,
4749) -> Result < WatchExit > {
@@ -110,6 +112,48 @@ pub fn watch(
110112 Ok ( WatchExit :: Shutdown )
111113}
112114
115+ fn watch_list_loop (
116+ app_state : & mut AppState ,
117+ notify_exercise_names : Option < & ' static [ & ' static [ u8 ] ] > ,
118+ ) -> Result < ( ) > {
119+ loop {
120+ match run_watch ( app_state, notify_exercise_names) ? {
121+ WatchExit :: Shutdown => break Ok ( ( ) ) ,
122+ // It is much easier to exit the watch mode, launch the list mode and then restart
123+ // the watch mode instead of trying to pause the watch threads and correct the
124+ // watch state.
125+ WatchExit :: List => list:: list ( app_state) ?,
126+ }
127+ }
128+ }
129+
130+ /// `notify_exercise_names` as None activates the manual run mode.
131+ pub fn watch (
132+ app_state : & mut AppState ,
133+ notify_exercise_names : Option < & ' static [ & ' static [ u8 ] ] > ,
134+ ) -> Result < ( ) > {
135+ #[ cfg( not( windows) ) ]
136+ {
137+ let stdin_fd = rustix:: stdio:: stdin ( ) ;
138+ let mut termios = rustix:: termios:: tcgetattr ( stdin_fd) ?;
139+ let original_local_modes = termios. local_modes ;
140+ // Disable stdin line buffering and hide input.
141+ termios. local_modes -=
142+ rustix:: termios:: LocalModes :: ICANON | rustix:: termios:: LocalModes :: ECHO ;
143+ rustix:: termios:: tcsetattr ( stdin_fd, rustix:: termios:: OptionalActions :: Now , & termios) ?;
144+
145+ let res = watch_list_loop ( app_state, notify_exercise_names) ;
146+
147+ termios. local_modes = original_local_modes;
148+ rustix:: termios:: tcsetattr ( stdin_fd, rustix:: termios:: OptionalActions :: Now , & termios) ?;
149+
150+ res
151+ }
152+
153+ #[ cfg( windows) ]
154+ watch_list_loop ( app_state, notify_exercise_names)
155+ }
156+
113157const QUIT_MSG : & [ u8 ] = b"
114158We hope you're enjoying learning Rust!
115159If you want to continue working on the exercises at a later point, you can simply run `rustlings` again.
0 commit comments