@@ -9,6 +9,7 @@ use crate::lock::LockKind;
99use crate :: queue:: FifoQueue ;
1010use crate :: queue:: * ;
1111use anyhow:: { Context , Result } ;
12+ use console:: Term ;
1213use futures_timer:: Delay ;
1314use notify:: event:: ModifyKind ;
1415use notify:: { Config , Error , Event , EventKind , RecommendedWatcher , RecursiveMode , Watcher } ;
@@ -177,6 +178,31 @@ fn carry_forward_compile_warnings(previous: &BuildCommandState, next: &mut Build
177178 }
178179}
179180
181+ fn should_clear_screen (
182+ clear_screen : bool ,
183+ show_progress : bool ,
184+ plain_output : bool ,
185+ initial_build : bool ,
186+ ) -> bool {
187+ clear_screen && show_progress && !plain_output && !initial_build
188+ }
189+
190+ fn clear_terminal_screen ( ) {
191+ let _ = Term :: stdout ( ) . clear_screen ( ) ;
192+ }
193+
194+ fn print_rebuild_header ( compile_type : CompileType ) {
195+ match compile_type {
196+ CompileType :: Incremental => println ! ( "Change detected. Rebuilding..." ) ,
197+ CompileType :: Full => println ! ( "Change detected. Full rebuild..." ) ,
198+ CompileType :: None => ( ) ,
199+ }
200+ }
201+
202+ fn print_build_failed_footer ( ) {
203+ println ! ( "\n Build failed. Watching for changes..." ) ;
204+ }
205+
180206struct AsyncWatchArgs < ' a > {
181207 watcher : & ' a mut RecommendedWatcher ,
182208 current_watch_paths : Vec < ( PathBuf , RecursiveMode ) > ,
@@ -188,6 +214,7 @@ struct AsyncWatchArgs<'a> {
188214 after_build : Option < String > ,
189215 create_sourcedirs : bool ,
190216 plain_output : bool ,
217+ clear_screen : bool ,
191218 prod : bool ,
192219}
193220
@@ -203,6 +230,7 @@ async fn async_watch(
203230 after_build,
204231 create_sourcedirs,
205232 plain_output,
233+ clear_screen,
206234 prod,
207235 } : AsyncWatchArgs < ' _ > ,
208236) -> Result < ( ) > {
@@ -377,40 +405,60 @@ async fn async_watch(
377405
378406 match needs_compile_type {
379407 CompileType :: Incremental => {
408+ if should_clear_screen ( clear_screen, show_progress, plain_output, initial_build) {
409+ clear_terminal_screen ( ) ;
410+ print_rebuild_header ( CompileType :: Incremental ) ;
411+ }
412+
380413 let timing_total = Instant :: now ( ) ;
381- if let Ok ( result) = build:: incremental_build (
414+ let result = build:: incremental_build (
382415 & mut build_state,
383416 None ,
384417 initial_build,
385418 show_progress,
386419 !initial_build,
387420 create_sourcedirs,
388421 plain_output,
389- ) {
390- if let Some ( a) = after_build. clone ( ) {
391- cmd:: run ( a)
422+ ) ;
423+
424+ match result {
425+ Ok ( result) => {
426+ if let Some ( a) = after_build. clone ( ) {
427+ cmd:: run ( a)
428+ }
429+ let timing_total_elapsed = timing_total. elapsed ( ) ;
430+ if show_progress {
431+ let compilation_type = if initial_build { "initial" } else { "incremental" } ;
432+ if plain_output {
433+ println ! ( "Finished {compilation_type} compilation" )
434+ } else {
435+ println ! (
436+ "\n {}\n " ,
437+ build:: format_finished_compilation_message(
438+ Some ( compilation_type) ,
439+ result,
440+ timing_total_elapsed,
441+ )
442+ ) ;
443+ }
444+ }
392445 }
393- let timing_total_elapsed = timing_total. elapsed ( ) ;
394- if show_progress {
395- let compilation_type = if initial_build { "initial" } else { "incremental" } ;
396- if plain_output {
397- println ! ( "Finished {compilation_type} compilation" )
398- } else {
399- println ! (
400- "\n {}\n " ,
401- build:: format_finished_compilation_message(
402- Some ( compilation_type) ,
403- result,
404- timing_total_elapsed,
405- )
406- ) ;
446+ Err ( _) => {
447+ if should_clear_screen ( clear_screen, show_progress, plain_output, initial_build) {
448+ print_build_failed_footer ( ) ;
407449 }
408450 }
409451 }
452+
410453 needs_compile_type = CompileType :: None ;
411454 initial_build = false ;
412455 }
413456 CompileType :: Full => {
457+ if should_clear_screen ( clear_screen, show_progress, plain_output, initial_build) {
458+ clear_terminal_screen ( ) ;
459+ print_rebuild_header ( CompileType :: Full ) ;
460+ }
461+
414462 let timing_total = Instant :: now ( ) ;
415463 let mut next_build_state = build:: initialize_build (
416464 None ,
@@ -443,17 +491,28 @@ async fn async_watch(
443491 create_sourcedirs,
444492 plain_output,
445493 ) ;
446- if let Ok ( result) = result {
447- if let Some ( a) = after_build. clone ( ) {
448- cmd:: run ( a)
449- }
494+ match result {
495+ Ok ( result) => {
496+ if let Some ( a) = after_build. clone ( ) {
497+ cmd:: run ( a)
498+ }
450499
451- let timing_total_elapsed = timing_total. elapsed ( ) ;
452- if !plain_output && show_progress {
453- println ! (
454- "\n {}\n " ,
455- build:: format_finished_compilation_message( None , result, timing_total_elapsed, )
456- ) ;
500+ let timing_total_elapsed = timing_total. elapsed ( ) ;
501+ if !plain_output && show_progress {
502+ println ! (
503+ "\n {}\n " ,
504+ build:: format_finished_compilation_message(
505+ None ,
506+ result,
507+ timing_total_elapsed,
508+ )
509+ ) ;
510+ }
511+ }
512+ Err ( _) => {
513+ if should_clear_screen ( clear_screen, show_progress, plain_output, initial_build) {
514+ print_build_failed_footer ( ) ;
515+ }
457516 }
458517 }
459518
@@ -479,6 +538,7 @@ pub fn start(
479538 create_sourcedirs : bool ,
480539 plain_output : bool ,
481540 warn_error : Option < String > ,
541+ clear_screen : bool ,
482542 prod : bool ,
483543) -> Result < ( ) > {
484544 futures:: executor:: block_on ( async {
@@ -518,6 +578,7 @@ pub fn start(
518578 after_build,
519579 create_sourcedirs,
520580 plain_output,
581+ clear_screen,
521582 prod,
522583 } )
523584 . await
@@ -648,6 +709,15 @@ mod tests {
648709 }
649710 }
650711
712+ #[ test]
713+ fn clears_screen_only_for_non_initial_interactive_rebuilds ( ) {
714+ assert ! ( should_clear_screen( true , true , false , false ) ) ;
715+ assert ! ( !should_clear_screen( true , true , false , true ) ) ;
716+ assert ! ( !should_clear_screen( true , true , true , false ) ) ;
717+ assert ! ( !should_clear_screen( true , false , false , false ) ) ;
718+ assert ! ( !should_clear_screen( false , true , false , false ) ) ;
719+ }
720+
651721 #[ test]
652722 fn carries_forward_implementation_warnings_for_matching_module_paths ( ) {
653723 let previous = test_build_state (
0 commit comments