diff options
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 56 |
1 files changed, 28 insertions, 28 deletions
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 15bf519c9..52c7e2bdb 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -9,7 +9,7 @@ use std::{error::Error, fmt, panic, path::PathBuf, sync::Arc, time::Instant}; | |||
9 | 9 | ||
10 | use crossbeam_channel::{select, unbounded, RecvError, Sender}; | 10 | use crossbeam_channel::{select, unbounded, RecvError, Sender}; |
11 | use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; | 11 | use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; |
12 | use lsp_types::{ClientCapabilities, NumberOrString, Url}; | 12 | use lsp_types::{ClientCapabilities, NumberOrString}; |
13 | use ra_cargo_watch::{CheckOptions, CheckTask}; | 13 | use ra_cargo_watch::{CheckOptions, CheckTask}; |
14 | use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId}; | 14 | use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId}; |
15 | use ra_prof::profile; | 15 | use ra_prof::profile; |
@@ -352,7 +352,7 @@ fn loop_turn( | |||
352 | world_state.maybe_collect_garbage(); | 352 | world_state.maybe_collect_garbage(); |
353 | loop_state.in_flight_libraries -= 1; | 353 | loop_state.in_flight_libraries -= 1; |
354 | } | 354 | } |
355 | Event::CheckWatcher(task) => on_check_task(task, world_state, task_sender)?, | 355 | Event::CheckWatcher(task) => on_check_task(pool, task, world_state, task_sender)?, |
356 | Event::Msg(msg) => match msg { | 356 | Event::Msg(msg) => match msg { |
357 | Message::Request(req) => on_request( | 357 | Message::Request(req) => on_request( |
358 | world_state, | 358 | world_state, |
@@ -602,31 +602,23 @@ fn on_notification( | |||
602 | } | 602 | } |
603 | 603 | ||
604 | fn on_check_task( | 604 | fn on_check_task( |
605 | pool: &ThreadPool, | ||
605 | task: CheckTask, | 606 | task: CheckTask, |
606 | world_state: &mut WorldState, | 607 | world_state: &mut WorldState, |
607 | task_sender: &Sender<Task>, | 608 | task_sender: &Sender<Task>, |
608 | ) -> Result<()> { | 609 | ) -> Result<()> { |
609 | match task { | 610 | let urls = match task { |
610 | CheckTask::ClearDiagnostics => { | 611 | CheckTask::ClearDiagnostics => { |
611 | let state = Arc::get_mut(&mut world_state.check_watcher.state) | 612 | let state = Arc::get_mut(&mut world_state.check_watcher.state) |
612 | .expect("couldn't get check watcher state as mutable"); | 613 | .expect("couldn't get check watcher state as mutable"); |
613 | let cleared_files = state.clear(); | 614 | state.clear() |
614 | |||
615 | // Send updated diagnostics for each cleared file | ||
616 | for url in cleared_files { | ||
617 | publish_diagnostics_for_url(&url, world_state, task_sender)?; | ||
618 | } | ||
619 | } | 615 | } |
620 | 616 | ||
621 | CheckTask::AddDiagnostic(url, diagnostic) => { | 617 | CheckTask::AddDiagnostic(url, diagnostic) => { |
622 | let state = Arc::get_mut(&mut world_state.check_watcher.state) | 618 | let state = Arc::get_mut(&mut world_state.check_watcher.state) |
623 | .expect("couldn't get check watcher state as mutable"); | 619 | .expect("couldn't get check watcher state as mutable"); |
624 | state.add_diagnostic_with_fixes(url.clone(), diagnostic); | 620 | state.add_diagnostic_with_fixes(url.clone(), diagnostic); |
625 | 621 | vec![url] | |
626 | // We manually send a diagnostic update when the watcher asks | ||
627 | // us to, to avoid the issue of having to change the file to | ||
628 | // receive updated diagnostics. | ||
629 | publish_diagnostics_for_url(&url, world_state, task_sender)?; | ||
630 | } | 622 | } |
631 | 623 | ||
632 | CheckTask::Status(progress) => { | 624 | CheckTask::Status(progress) => { |
@@ -636,22 +628,30 @@ fn on_check_task( | |||
636 | }; | 628 | }; |
637 | let not = notification_new::<req::Progress>(params); | 629 | let not = notification_new::<req::Progress>(params); |
638 | task_sender.send(Task::Notify(not)).unwrap(); | 630 | task_sender.send(Task::Notify(not)).unwrap(); |
631 | Vec::new() | ||
639 | } | 632 | } |
640 | } | 633 | }; |
641 | Ok(()) | 634 | |
642 | } | 635 | let subscriptions = urls |
636 | .into_iter() | ||
637 | .map(|url| { | ||
638 | let path = url.to_file_path().map_err(|()| format!("invalid uri: {}", url))?; | ||
639 | Ok(world_state.vfs.read().path2file(&path).map(|it| FileId(it.0))) | ||
640 | }) | ||
641 | .filter_map(|res| res.transpose()) | ||
642 | .collect::<Result<Vec<_>>>()?; | ||
643 | |||
644 | // We manually send a diagnostic update when the watcher asks | ||
645 | // us to, to avoid the issue of having to change the file to | ||
646 | // receive updated diagnostics. | ||
647 | update_file_notifications_on_threadpool( | ||
648 | pool, | ||
649 | world_state.snapshot(), | ||
650 | false, | ||
651 | task_sender.clone(), | ||
652 | subscriptions, | ||
653 | ); | ||
643 | 654 | ||
644 | fn publish_diagnostics_for_url( | ||
645 | url: &Url, | ||
646 | world_state: &WorldState, | ||
647 | task_sender: &Sender<Task>, | ||
648 | ) -> Result<()> { | ||
649 | let path = url.to_file_path().map_err(|()| format!("invalid uri: {}", url))?; | ||
650 | if let Some(file_id) = world_state.vfs.read().path2file(&path) { | ||
651 | let params = handlers::publish_diagnostics(&world_state.snapshot(), FileId(file_id.0))?; | ||
652 | let not = notification_new::<req::PublishDiagnostics>(params); | ||
653 | task_sender.send(Task::Notify(not)).unwrap(); | ||
654 | } | ||
655 | Ok(()) | 655 | Ok(()) |
656 | } | 656 | } |
657 | 657 | ||