diff options
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop.rs')
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 79 |
1 files changed, 56 insertions, 23 deletions
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 84012b99d..7822be2e2 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}; | 12 | use lsp_types::{ClientCapabilities, NumberOrString, Url}; |
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; |
@@ -336,28 +336,7 @@ fn loop_turn( | |||
336 | world_state.maybe_collect_garbage(); | 336 | world_state.maybe_collect_garbage(); |
337 | loop_state.in_flight_libraries -= 1; | 337 | loop_state.in_flight_libraries -= 1; |
338 | } | 338 | } |
339 | Event::CheckWatcher(task) => match task { | 339 | Event::CheckWatcher(task) => on_check_task(task, world_state, task_sender)?, |
340 | CheckTask::Update(uri) => { | ||
341 | // We manually send a diagnostic update when the watcher asks | ||
342 | // us to, to avoid the issue of having to change the file to | ||
343 | // receive updated diagnostics. | ||
344 | let path = uri.to_file_path().map_err(|()| format!("invalid uri: {}", uri))?; | ||
345 | if let Some(file_id) = world_state.vfs.read().path2file(&path) { | ||
346 | let params = | ||
347 | handlers::publish_diagnostics(&world_state.snapshot(), FileId(file_id.0))?; | ||
348 | let not = notification_new::<req::PublishDiagnostics>(params); | ||
349 | task_sender.send(Task::Notify(not)).unwrap(); | ||
350 | } | ||
351 | } | ||
352 | CheckTask::Status(progress) => { | ||
353 | let params = req::ProgressParams { | ||
354 | token: req::ProgressToken::String("rustAnalyzer/cargoWatcher".to_string()), | ||
355 | value: req::ProgressParamsValue::WorkDone(progress), | ||
356 | }; | ||
357 | let not = notification_new::<req::Progress>(params); | ||
358 | task_sender.send(Task::Notify(not)).unwrap(); | ||
359 | } | ||
360 | }, | ||
361 | Event::Msg(msg) => match msg { | 340 | Event::Msg(msg) => match msg { |
362 | Message::Request(req) => on_request( | 341 | Message::Request(req) => on_request( |
363 | world_state, | 342 | world_state, |
@@ -605,6 +584,60 @@ fn on_notification( | |||
605 | Ok(()) | 584 | Ok(()) |
606 | } | 585 | } |
607 | 586 | ||
587 | fn on_check_task( | ||
588 | task: CheckTask, | ||
589 | world_state: &WorldState, | ||
590 | task_sender: &Sender<Task>, | ||
591 | ) -> Result<()> { | ||
592 | match task { | ||
593 | CheckTask::ClearDiagnostics => { | ||
594 | let cleared_files = world_state.check_watcher.state.write().clear(); | ||
595 | |||
596 | // Send updated diagnostics for each cleared file | ||
597 | for url in cleared_files { | ||
598 | publish_diagnostics_for_url(&url, world_state, task_sender)?; | ||
599 | } | ||
600 | } | ||
601 | |||
602 | CheckTask::AddDiagnostic(url, diagnostic) => { | ||
603 | world_state | ||
604 | .check_watcher | ||
605 | .state | ||
606 | .write() | ||
607 | .add_diagnostic_with_fixes(url.clone(), diagnostic); | ||
608 | |||
609 | // We manually send a diagnostic update when the watcher asks | ||
610 | // us to, to avoid the issue of having to change the file to | ||
611 | // receive updated diagnostics. | ||
612 | publish_diagnostics_for_url(&url, world_state, task_sender)?; | ||
613 | } | ||
614 | |||
615 | CheckTask::Status(progress) => { | ||
616 | let params = req::ProgressParams { | ||
617 | token: req::ProgressToken::String("rustAnalyzer/cargoWatcher".to_string()), | ||
618 | value: req::ProgressParamsValue::WorkDone(progress), | ||
619 | }; | ||
620 | let not = notification_new::<req::Progress>(params); | ||
621 | task_sender.send(Task::Notify(not)).unwrap(); | ||
622 | } | ||
623 | } | ||
624 | Ok(()) | ||
625 | } | ||
626 | |||
627 | fn publish_diagnostics_for_url( | ||
628 | url: &Url, | ||
629 | world_state: &WorldState, | ||
630 | task_sender: &Sender<Task>, | ||
631 | ) -> Result<()> { | ||
632 | let path = url.to_file_path().map_err(|()| format!("invalid uri: {}", url))?; | ||
633 | if let Some(file_id) = world_state.vfs.read().path2file(&path) { | ||
634 | let params = handlers::publish_diagnostics(&world_state.snapshot(), FileId(file_id.0))?; | ||
635 | let not = notification_new::<req::PublishDiagnostics>(params); | ||
636 | task_sender.send(Task::Notify(not)).unwrap(); | ||
637 | } | ||
638 | Ok(()) | ||
639 | } | ||
640 | |||
608 | struct PoolDispatcher<'a> { | 641 | struct PoolDispatcher<'a> { |
609 | req: Option<Request>, | 642 | req: Option<Request>, |
610 | pool: &'a ThreadPool, | 643 | pool: &'a ThreadPool, |