@@ -406,25 +406,49 @@ impl GlobalState {
406
406
}
407
407
408
408
let state_changed = self . process_changes ( ) ;
409
+ let memdocs_added_or_removed = self . mem_docs . take_changes ( ) ;
409
410
410
- if self . is_quiescent ( ) && !was_quiescent {
411
- for flycheck in & self . flycheck {
412
- flycheck. update ( ) ;
411
+ if self . is_quiescent ( ) {
412
+ if !was_quiescent {
413
+ for flycheck in & self . flycheck {
414
+ flycheck. update ( ) ;
415
+ }
413
416
}
414
- }
415
417
416
- if self . is_quiescent ( ) && ( !was_quiescent || state_changed) {
417
- self . update_file_notifications_on_threadpool ( ) ;
418
+ if !was_quiescent || state_changed {
419
+ // Ensure that only one cache priming task can run at a time
420
+ self . prime_caches_queue . request_op ( ) ;
421
+ if self . prime_caches_queue . should_start_op ( ) {
422
+ self . task_pool . handle . spawn_with_sender ( {
423
+ let snap = self . snapshot ( ) ;
424
+ move |sender| {
425
+ let cb = |progress| {
426
+ sender. send ( Task :: PrimeCaches ( progress) ) . unwrap ( ) ;
427
+ } ;
428
+ match snap. analysis . prime_caches ( cb) {
429
+ Ok ( ( ) ) => ( ) ,
430
+ Err ( _canceled) => ( ) ,
431
+ }
432
+ }
433
+ } ) ;
434
+ }
418
435
419
- // Refresh semantic tokens if the client supports it.
420
- if self . config . semantic_tokens_refresh ( ) {
421
- self . semantic_tokens_cache . lock ( ) . clear ( ) ;
422
- self . send_request :: < lsp_types:: request:: SemanticTokensRefesh > ( ( ) , |_, _| ( ) ) ;
436
+ // Refresh semantic tokens if the client supports it.
437
+ if self . config . semantic_tokens_refresh ( ) {
438
+ self . semantic_tokens_cache . lock ( ) . clear ( ) ;
439
+ self . send_request :: < lsp_types:: request:: SemanticTokensRefesh > ( ( ) , |_, _| ( ) ) ;
440
+ }
441
+
442
+ // Refresh code lens if the client supports it.
443
+ if self . config . code_lens_refresh ( ) {
444
+ self . send_request :: < lsp_types:: request:: CodeLensRefresh > ( ( ) , |_, _| ( ) ) ;
445
+ }
423
446
}
424
447
425
- // Refresh code lens if the client supports it.
426
- if self . config . code_lens_refresh ( ) {
427
- self . send_request :: < lsp_types:: request:: CodeLensRefresh > ( ( ) , |_, _| ( ) ) ;
448
+ if !was_quiescent || state_changed || memdocs_added_or_removed {
449
+ if self . config . publish_diagnostics ( ) {
450
+ self . update_diagnostics ( )
451
+ }
428
452
}
429
453
}
430
454
@@ -586,42 +610,32 @@ impl GlobalState {
586
610
{
587
611
log:: error!( "duplicate DidOpenTextDocument: {}" , path)
588
612
}
589
- let changed = this
590
- . vfs
613
+ this. vfs
591
614
. write ( )
592
615
. 0
593
616
. set_file_contents ( path, Some ( params. text_document . text . into_bytes ( ) ) ) ;
594
-
595
- // If the VFS contents are unchanged, update diagnostics, since `handle_event`
596
- // won't see any changes. This avoids missing diagnostics when opening a file.
597
- //
598
- // If the file *was* changed, `handle_event` will already recompute and send
599
- // diagnostics. We can't do it here, since the *current* file contents might be
600
- // unset in salsa, since the VFS change hasn't been applied to the database yet.
601
- if !changed {
602
- this. maybe_update_diagnostics ( ) ;
603
- }
604
617
}
605
618
Ok ( ( ) )
606
619
} ) ?
607
620
. on :: < lsp_types:: notification:: DidChangeTextDocument > ( |this, params| {
608
621
if let Ok ( path) = from_proto:: vfs_path ( & params. text_document . uri ) {
609
- let doc = match this. mem_docs . get_mut ( & path) {
610
- Some ( doc) => doc,
622
+ match this. mem_docs . get_mut ( & path) {
623
+ Some ( doc) => {
624
+ // The version passed in DidChangeTextDocument is the version after all edits are applied
625
+ // so we should apply it before the vfs is notified.
626
+ doc. version = params. text_document . version ;
627
+ }
611
628
None => {
612
629
log:: error!( "expected DidChangeTextDocument: {}" , path) ;
613
630
return Ok ( ( ) ) ;
614
631
}
615
632
} ;
633
+
616
634
let vfs = & mut this. vfs . write ( ) . 0 ;
617
635
let file_id = vfs. file_id ( & path) . unwrap ( ) ;
618
636
let mut text = String :: from_utf8 ( vfs. file_contents ( file_id) . to_vec ( ) ) . unwrap ( ) ;
619
637
apply_document_changes ( & mut text, params. content_changes ) ;
620
638
621
- // The version passed in DidChangeTextDocument is the version after all edits are applied
622
- // so we should apply it before the vfs is notified.
623
- doc. version = params. text_document . version ;
624
-
625
639
vfs. set_file_contents ( path. clone ( ) , Some ( text. into_bytes ( ) ) ) ;
626
640
}
627
641
Ok ( ( ) )
@@ -696,53 +710,33 @@ impl GlobalState {
696
710
. finish ( ) ;
697
711
Ok ( ( ) )
698
712
}
699
- fn update_file_notifications_on_threadpool ( & mut self ) {
700
- self . maybe_update_diagnostics ( ) ;
701
-
702
- // Ensure that only one cache priming task can run at a time
703
- self . prime_caches_queue . request_op ( ) ;
704
- if self . prime_caches_queue . should_start_op ( ) {
705
- self . task_pool . handle . spawn_with_sender ( {
706
- let snap = self . snapshot ( ) ;
707
- move |sender| {
708
- let cb = |progress| {
709
- sender. send ( Task :: PrimeCaches ( progress) ) . unwrap ( ) ;
710
- } ;
711
- match snap. analysis . prime_caches ( cb) {
712
- Ok ( ( ) ) => ( ) ,
713
- Err ( _canceled) => ( ) ,
714
- }
715
- }
716
- } ) ;
717
- }
718
- }
719
- fn maybe_update_diagnostics ( & mut self ) {
713
+
714
+ fn update_diagnostics ( & mut self ) {
720
715
let subscriptions = self
721
716
. mem_docs
722
717
. iter ( )
723
718
. map ( |path| self . vfs . read ( ) . 0 . file_id ( path) . unwrap ( ) )
724
719
. collect :: < Vec < _ > > ( ) ;
725
720
726
721
log:: trace!( "updating notifications for {:?}" , subscriptions) ;
727
- if self . config . publish_diagnostics ( ) {
728
- let snapshot = self . snapshot ( ) ;
729
- self . task_pool . handle . spawn ( move || {
730
- let diagnostics = subscriptions
731
- . into_iter ( )
732
- . filter_map ( |file_id| {
733
- handlers:: publish_diagnostics ( & snapshot, file_id)
734
- . map_err ( |err| {
735
- if !is_cancelled ( & * err) {
736
- log:: error!( "failed to compute diagnostics: {:?}" , err) ;
737
- }
738
- ( )
739
- } )
740
- . ok ( )
741
- . map ( |diags| ( file_id, diags) )
742
- } )
743
- . collect :: < Vec < _ > > ( ) ;
744
- Task :: Diagnostics ( diagnostics)
745
- } )
746
- }
722
+
723
+ let snapshot = self . snapshot ( ) ;
724
+ self . task_pool . handle . spawn ( move || {
725
+ let diagnostics = subscriptions
726
+ . into_iter ( )
727
+ . filter_map ( |file_id| {
728
+ handlers:: publish_diagnostics ( & snapshot, file_id)
729
+ . map_err ( |err| {
730
+ if !is_cancelled ( & * err) {
731
+ log:: error!( "failed to compute diagnostics: {:?}" , err) ;
732
+ }
733
+ ( )
734
+ } )
735
+ . ok ( )
736
+ . map ( |diags| ( file_id, diags) )
737
+ } )
738
+ . collect :: < Vec < _ > > ( ) ;
739
+ Task :: Diagnostics ( diagnostics)
740
+ } )
747
741
}
748
742
}
0 commit comments