@@ -31,7 +31,7 @@ use crate::{
31
31
use log:: { debug, error, warn} ;
32
32
use std:: {
33
33
io:: { stdin, stdout, Write } ,
34
- sync:: { atomic :: Ordering , Arc } ,
34
+ sync:: Arc ,
35
35
time:: { Duration , Instant } ,
36
36
} ;
37
37
@@ -274,17 +274,26 @@ impl Application {
274
274
}
275
275
276
276
#[ cfg( feature = "integration" ) ]
277
- fn render ( & mut self ) { }
277
+ async fn render ( & mut self ) { }
278
278
279
279
#[ cfg( not( feature = "integration" ) ) ]
280
- fn render ( & mut self ) {
280
+ async fn render ( & mut self ) {
281
281
let mut cx = crate :: compositor:: Context {
282
282
editor : & mut self . editor ,
283
283
jobs : & mut self . jobs ,
284
284
scroll : None ,
285
285
} ;
286
286
287
- cx. editor . redraw_handle . store ( false , Ordering :: Relaxed ) ;
287
+ // Aquire mutable access to the redraw_handle lock
288
+ // to ensure that there are no tasks running that want to block rendering
289
+ drop ( cx. editor . redraw_handle . 1 . write ( ) . await ) ;
290
+ cx. editor . needs_redraw = false ;
291
+ {
292
+ // exhaust any leftover redraw notifications
293
+ let notify = cx. editor . redraw_handle . 0 . notified ( ) ;
294
+ tokio:: pin!( notify) ;
295
+ notify. enable ( ) ;
296
+ }
288
297
289
298
let area = self
290
299
. terminal
@@ -306,7 +315,7 @@ impl Application {
306
315
where
307
316
S : Stream < Item = crossterm:: Result < crossterm:: event:: Event > > + Unpin ,
308
317
{
309
- self . render ( ) ;
318
+ self . render ( ) . await ;
310
319
self . last_render = Instant :: now ( ) ;
311
320
312
321
loop {
@@ -331,18 +340,18 @@ impl Application {
331
340
biased;
332
341
333
342
Some ( event) = input_stream. next( ) => {
334
- self . handle_terminal_events( event) ;
343
+ self . handle_terminal_events( event) . await ;
335
344
}
336
345
Some ( signal) = self . signals. next( ) => {
337
346
self . handle_signals( signal) . await ;
338
347
}
339
348
Some ( callback) = self . jobs. futures. next( ) => {
340
349
self . jobs. handle_callback( & mut self . editor, & mut self . compositor, callback) ;
341
- self . render( ) ;
350
+ self . render( ) . await ;
342
351
}
343
352
Some ( callback) = self . jobs. wait_futures. next( ) => {
344
353
self . jobs. handle_callback( & mut self . editor, & mut self . compositor, callback) ;
345
- self . render( ) ;
354
+ self . render( ) . await ;
346
355
}
347
356
event = self . editor. wait_event( ) => {
348
357
let _idle_handled = self . handle_editor_event( event) . await ;
@@ -447,25 +456,25 @@ impl Application {
447
456
self . compositor . resize ( area) ;
448
457
self . terminal . clear ( ) . expect ( "couldn't clear terminal" ) ;
449
458
450
- self . render ( ) ;
459
+ self . render ( ) . await ;
451
460
}
452
461
signal:: SIGUSR1 => {
453
462
self . refresh_config ( ) ;
454
- self . render ( ) ;
463
+ self . render ( ) . await ;
455
464
}
456
465
_ => unreachable ! ( ) ,
457
466
}
458
467
}
459
468
460
- pub fn handle_idle_timeout ( & mut self ) {
469
+ pub async fn handle_idle_timeout ( & mut self ) {
461
470
let mut cx = crate :: compositor:: Context {
462
471
editor : & mut self . editor ,
463
472
jobs : & mut self . jobs ,
464
473
scroll : None ,
465
474
} ;
466
475
let should_render = self . compositor . handle_event ( & Event :: IdleTimeout , & mut cx) ;
467
- if should_render || self . editor . redraw_handle . load ( Ordering :: Relaxed ) {
468
- self . render ( ) ;
476
+ if should_render || self . editor . needs_redraw {
477
+ self . render ( ) . await ;
469
478
}
470
479
}
471
480
@@ -538,31 +547,31 @@ impl Application {
538
547
match event {
539
548
EditorEvent :: DocumentSaved ( event) => {
540
549
self . handle_document_write ( event) ;
541
- self . render ( ) ;
550
+ self . render ( ) . await ;
542
551
}
543
552
EditorEvent :: ConfigEvent ( event) => {
544
553
self . handle_config_events ( event) ;
545
- self . render ( ) ;
554
+ self . render ( ) . await ;
546
555
}
547
556
EditorEvent :: LanguageServerMessage ( ( id, call) ) => {
548
557
self . handle_language_server_message ( call, id) . await ;
549
558
// limit render calls for fast language server messages
550
559
let last = self . editor . language_servers . incoming . is_empty ( ) ;
551
560
552
561
if last || self . last_render . elapsed ( ) > LSP_DEADLINE {
553
- self . render ( ) ;
562
+ self . render ( ) . await ;
554
563
self . last_render = Instant :: now ( ) ;
555
564
}
556
565
}
557
566
EditorEvent :: DebuggerEvent ( payload) => {
558
567
let needs_render = self . editor . handle_debugger_message ( payload) . await ;
559
568
if needs_render {
560
- self . render ( ) ;
569
+ self . render ( ) . await ;
561
570
}
562
571
}
563
572
EditorEvent :: IdleTimer => {
564
573
self . editor . clear_idle_timer ( ) ;
565
- self . handle_idle_timeout ( ) ;
574
+ self . handle_idle_timeout ( ) . await ;
566
575
567
576
#[ cfg( feature = "integration" ) ]
568
577
{
@@ -574,7 +583,10 @@ impl Application {
574
583
false
575
584
}
576
585
577
- pub fn handle_terminal_events ( & mut self , event : Result < CrosstermEvent , crossterm:: ErrorKind > ) {
586
+ pub async fn handle_terminal_events (
587
+ & mut self ,
588
+ event : Result < CrosstermEvent , crossterm:: ErrorKind > ,
589
+ ) {
578
590
let mut cx = crate :: compositor:: Context {
579
591
editor : & mut self . editor ,
580
592
jobs : & mut self . jobs ,
@@ -598,7 +610,7 @@ impl Application {
598
610
} ;
599
611
600
612
if should_redraw && !self . editor . should_close ( ) {
601
- self . render ( ) ;
613
+ self . render ( ) . await ;
602
614
}
603
615
}
604
616
0 commit comments