diff options
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 73 | ||||
-rw-r--r-- | crates/rust-analyzer/tests/heavy_tests/support.rs | 15 |
2 files changed, 77 insertions, 11 deletions
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index eb29e8322..1fefc66aa 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -16,7 +16,10 @@ use std::{ | |||
16 | 16 | ||
17 | use crossbeam_channel::{select, unbounded, RecvError, Sender}; | 17 | use crossbeam_channel::{select, unbounded, RecvError, Sender}; |
18 | use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; | 18 | use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; |
19 | use lsp_types::{ClientCapabilities, NumberOrString}; | 19 | use lsp_types::{ |
20 | ClientCapabilities, NumberOrString, WorkDoneProgress, WorkDoneProgressBegin, | ||
21 | WorkDoneProgressCreateParams, WorkDoneProgressEnd, WorkDoneProgressReport, | ||
22 | }; | ||
20 | use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckTask}; | 23 | use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckTask}; |
21 | use ra_ide::{Canceled, FileId, InlayHintsOptions, LibraryData, SourceRootId}; | 24 | use ra_ide::{Canceled, FileId, InlayHintsOptions, LibraryData, SourceRootId}; |
22 | use ra_prof::profile; | 25 | use ra_prof::profile; |
@@ -330,6 +333,7 @@ struct LoopState { | |||
330 | in_flight_libraries: usize, | 333 | in_flight_libraries: usize, |
331 | pending_libraries: Vec<(SourceRootId, Vec<(FileId, RelativePathBuf, Arc<String>)>)>, | 334 | pending_libraries: Vec<(SourceRootId, Vec<(FileId, RelativePathBuf, Arc<String>)>)>, |
332 | workspace_loaded: bool, | 335 | workspace_loaded: bool, |
336 | roots_scanned_progress: Option<usize>, | ||
333 | } | 337 | } |
334 | 338 | ||
335 | impl LoopState { | 339 | impl LoopState { |
@@ -429,17 +433,15 @@ fn loop_turn( | |||
429 | && loop_state.in_flight_libraries == 0 | 433 | && loop_state.in_flight_libraries == 0 |
430 | { | 434 | { |
431 | loop_state.workspace_loaded = true; | 435 | loop_state.workspace_loaded = true; |
432 | let n_packages: usize = world_state.workspaces.iter().map(|it| it.n_packages()).sum(); | ||
433 | if world_state.feature_flags.get("notifications.workspace-loaded") { | ||
434 | let msg = format!("workspace loaded, {} rust packages", n_packages); | ||
435 | show_message(req::MessageType::Info, msg, &connection.sender); | ||
436 | } | ||
437 | world_state.check_watcher.update(); | 436 | world_state.check_watcher.update(); |
438 | pool.execute({ | 437 | pool.execute({ |
439 | let subs = loop_state.subscriptions.subscriptions(); | 438 | let subs = loop_state.subscriptions.subscriptions(); |
440 | let snap = world_state.snapshot(); | 439 | let snap = world_state.snapshot(); |
441 | move || snap.analysis().prime_caches(subs).unwrap_or_else(|_: Canceled| ()) | 440 | move || snap.analysis().prime_caches(subs).unwrap_or_else(|_: Canceled| ()) |
442 | }); | 441 | }); |
442 | send_startup_progress(&connection.sender, loop_state, world_state); | ||
443 | } else if !loop_state.workspace_loaded { | ||
444 | send_startup_progress(&connection.sender, loop_state, world_state); | ||
443 | } | 445 | } |
444 | 446 | ||
445 | if state_changed { | 447 | if state_changed { |
@@ -704,6 +706,65 @@ fn on_diagnostic_task(task: DiagnosticTask, msg_sender: &Sender<Message>, state: | |||
704 | } | 706 | } |
705 | } | 707 | } |
706 | 708 | ||
709 | fn send_startup_progress( | ||
710 | sender: &Sender<Message>, | ||
711 | loop_state: &mut LoopState, | ||
712 | world_state: &WorldState, | ||
713 | ) { | ||
714 | if !world_state.feature_flags.get("notifications.workspace-loaded") { | ||
715 | return; | ||
716 | } | ||
717 | |||
718 | let total: usize = world_state.workspaces.iter().map(|it| it.n_packages()).sum(); | ||
719 | let prev_progress = loop_state.roots_scanned_progress; | ||
720 | let progress = total - world_state.roots_to_scan; | ||
721 | loop_state.roots_scanned_progress = Some(progress); | ||
722 | |||
723 | match (prev_progress, loop_state.workspace_loaded) { | ||
724 | (None, false) => { | ||
725 | let work_done_progress_create = request_new::<req::WorkDoneProgressCreate>( | ||
726 | loop_state.next_request_id(), | ||
727 | WorkDoneProgressCreateParams { | ||
728 | token: req::ProgressToken::String("rustAnalyzer/startup".into()), | ||
729 | }, | ||
730 | ); | ||
731 | sender.send(work_done_progress_create.into()).unwrap(); | ||
732 | send_startup_progress_notif( | ||
733 | sender, | ||
734 | WorkDoneProgress::Begin(WorkDoneProgressBegin { | ||
735 | title: "rust-analyzer".into(), | ||
736 | cancellable: None, | ||
737 | message: Some(format!("{}/{} packages", progress, total)), | ||
738 | percentage: Some(100.0 * progress as f64 / total as f64), | ||
739 | }), | ||
740 | ); | ||
741 | } | ||
742 | (Some(prev), false) if progress != prev => send_startup_progress_notif( | ||
743 | sender, | ||
744 | WorkDoneProgress::Report(WorkDoneProgressReport { | ||
745 | cancellable: None, | ||
746 | message: Some(format!("{}/{} packages", progress, total)), | ||
747 | percentage: Some(100.0 * progress as f64 / total as f64), | ||
748 | }), | ||
749 | ), | ||
750 | (_, true) => send_startup_progress_notif( | ||
751 | sender, | ||
752 | WorkDoneProgress::End(WorkDoneProgressEnd { | ||
753 | message: Some(format!("rust-analyzer loaded, {} packages", progress)), | ||
754 | }), | ||
755 | ), | ||
756 | _ => {} | ||
757 | } | ||
758 | } | ||
759 | |||
760 | fn send_startup_progress_notif(sender: &Sender<Message>, work_done_progress: WorkDoneProgress) { | ||
761 | let notif = notification_new::<req::Progress>(req::ProgressParams { | ||
762 | token: req::ProgressToken::String("rustAnalyzer/startup".into()), | ||
763 | value: req::ProgressParamsValue::WorkDone(work_done_progress), | ||
764 | }); | ||
765 | sender.send(notif.into()).unwrap(); | ||
766 | } | ||
767 | |||
707 | struct PoolDispatcher<'a> { | 768 | struct PoolDispatcher<'a> { |
708 | req: Option<Request>, | 769 | req: Option<Request>, |
709 | pool: &'a ThreadPool, | 770 | pool: &'a ThreadPool, |
diff --git a/crates/rust-analyzer/tests/heavy_tests/support.rs b/crates/rust-analyzer/tests/heavy_tests/support.rs index e28ae61fe..1d7062bdf 100644 --- a/crates/rust-analyzer/tests/heavy_tests/support.rs +++ b/crates/rust-analyzer/tests/heavy_tests/support.rs | |||
@@ -12,13 +12,14 @@ use lsp_types::{ | |||
12 | notification::{DidOpenTextDocument, Exit}, | 12 | notification::{DidOpenTextDocument, Exit}, |
13 | request::Shutdown, | 13 | request::Shutdown, |
14 | ClientCapabilities, DidOpenTextDocumentParams, GotoCapability, TextDocumentClientCapabilities, | 14 | ClientCapabilities, DidOpenTextDocumentParams, GotoCapability, TextDocumentClientCapabilities, |
15 | TextDocumentIdentifier, TextDocumentItem, Url, | 15 | TextDocumentIdentifier, TextDocumentItem, Url, WorkDoneProgress, |
16 | }; | 16 | }; |
17 | use serde::Serialize; | 17 | use serde::Serialize; |
18 | use serde_json::{to_string_pretty, Value}; | 18 | use serde_json::{to_string_pretty, Value}; |
19 | use tempfile::TempDir; | 19 | use tempfile::TempDir; |
20 | use test_utils::{find_mismatch, parse_fixture}; | 20 | use test_utils::{find_mismatch, parse_fixture}; |
21 | 21 | ||
22 | use req::{ProgressParams, ProgressParamsValue}; | ||
22 | use rust_analyzer::{main_loop, req, ServerConfig}; | 23 | use rust_analyzer::{main_loop, req, ServerConfig}; |
23 | 24 | ||
24 | pub struct Project<'a> { | 25 | pub struct Project<'a> { |
@@ -201,10 +202,14 @@ impl Server { | |||
201 | } | 202 | } |
202 | pub fn wait_until_workspace_is_loaded(&self) { | 203 | pub fn wait_until_workspace_is_loaded(&self) { |
203 | self.wait_for_message_cond(1, &|msg: &Message| match msg { | 204 | self.wait_for_message_cond(1, &|msg: &Message| match msg { |
204 | Message::Notification(n) if n.method == "window/showMessage" => { | 205 | Message::Notification(n) if n.method == "$/progress" => { |
205 | let msg = | 206 | match n.clone().extract::<ProgressParams>("$/progress").unwrap() { |
206 | n.clone().extract::<req::ShowMessageParams>("window/showMessage").unwrap(); | 207 | ProgressParams { |
207 | msg.message.starts_with("workspace loaded") | 208 | token: req::ProgressToken::String(ref token), |
209 | value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(_)), | ||
210 | } if token == "rustAnalyzer/startup" => true, | ||
211 | _ => false, | ||
212 | } | ||
208 | } | 213 | } |
209 | _ => false, | 214 | _ => false, |
210 | }) | 215 | }) |