diff options
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 71 |
1 files changed, 65 insertions, 6 deletions
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 2b3b16d35..eb41e3cda 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; |
@@ -329,6 +332,7 @@ struct LoopState { | |||
329 | in_flight_libraries: usize, | 332 | in_flight_libraries: usize, |
330 | pending_libraries: Vec<(SourceRootId, Vec<(FileId, RelativePathBuf, Arc<String>)>)>, | 333 | pending_libraries: Vec<(SourceRootId, Vec<(FileId, RelativePathBuf, Arc<String>)>)>, |
331 | workspace_loaded: bool, | 334 | workspace_loaded: bool, |
335 | roots_scanned_progress: Option<usize>, | ||
332 | } | 336 | } |
333 | 337 | ||
334 | impl LoopState { | 338 | impl LoopState { |
@@ -428,11 +432,6 @@ fn loop_turn( | |||
428 | && loop_state.in_flight_libraries == 0 | 432 | && loop_state.in_flight_libraries == 0 |
429 | { | 433 | { |
430 | loop_state.workspace_loaded = true; | 434 | loop_state.workspace_loaded = true; |
431 | let n_packages: usize = world_state.workspaces.iter().map(|it| it.n_packages()).sum(); | ||
432 | if world_state.feature_flags.get("notifications.workspace-loaded") { | ||
433 | let msg = format!("workspace loaded, {} rust packages", n_packages); | ||
434 | show_message(req::MessageType::Info, msg, &connection.sender); | ||
435 | } | ||
436 | world_state.check_watcher.update(); | 435 | world_state.check_watcher.update(); |
437 | pool.execute({ | 436 | pool.execute({ |
438 | let subs = loop_state.subscriptions.subscriptions(); | 437 | let subs = loop_state.subscriptions.subscriptions(); |
@@ -440,6 +439,7 @@ fn loop_turn( | |||
440 | move || snap.analysis().prime_caches(subs).unwrap_or_else(|_: Canceled| ()) | 439 | move || snap.analysis().prime_caches(subs).unwrap_or_else(|_: Canceled| ()) |
441 | }); | 440 | }); |
442 | } | 441 | } |
442 | send_startup_progress(&connection.sender, loop_state, world_state); | ||
443 | 443 | ||
444 | if state_changed { | 444 | if state_changed { |
445 | update_file_notifications_on_threadpool( | 445 | update_file_notifications_on_threadpool( |
@@ -703,6 +703,65 @@ fn on_diagnostic_task(task: DiagnosticTask, msg_sender: &Sender<Message>, state: | |||
703 | } | 703 | } |
704 | } | 704 | } |
705 | 705 | ||
706 | fn send_startup_progress( | ||
707 | sender: &Sender<Message>, | ||
708 | loop_state: &mut LoopState, | ||
709 | world_state: &WorldState, | ||
710 | ) { | ||
711 | if !world_state.feature_flags.get("notifications.workspace-loaded") { | ||
712 | return; | ||
713 | } | ||
714 | let total: usize = world_state.workspaces.iter().map(|it| it.n_packages()).sum(); | ||
715 | let progress = total - world_state.roots_to_scan; | ||
716 | if loop_state.roots_scanned_progress == Some(progress) { | ||
717 | return; | ||
718 | } | ||
719 | loop_state.roots_scanned_progress = Some(progress); | ||
720 | |||
721 | match (progress, loop_state.workspace_loaded) { | ||
722 | (0, false) => { | ||
723 | let work_done_progress_create = request_new::<req::WorkDoneProgressCreate>( | ||
724 | loop_state.next_request_id(), | ||
725 | WorkDoneProgressCreateParams { | ||
726 | token: req::ProgressToken::String("rustAnalyzer/startup".into()), | ||
727 | }, | ||
728 | ); | ||
729 | sender.send(work_done_progress_create.into()).unwrap(); | ||
730 | send_startup_progress_notif( | ||
731 | sender, | ||
732 | WorkDoneProgress::Begin(WorkDoneProgressBegin { | ||
733 | title: "rust-analyzer".into(), | ||
734 | cancellable: None, | ||
735 | message: Some(format!("{}/{} packages", progress, total)), | ||
736 | percentage: Some(100 as f64 * progress as f64 / total as f64), | ||
737 | }), | ||
738 | ); | ||
739 | } | ||
740 | (_, false) => send_startup_progress_notif( | ||
741 | sender, | ||
742 | WorkDoneProgress::Report(WorkDoneProgressReport { | ||
743 | cancellable: None, | ||
744 | message: Some(format!("{}/{} packages", progress, total)), | ||
745 | percentage: Some(100 as f64 * progress as f64 / total as f64), | ||
746 | }), | ||
747 | ), | ||
748 | (_, true) => send_startup_progress_notif( | ||
749 | sender, | ||
750 | WorkDoneProgress::End(WorkDoneProgressEnd { | ||
751 | message: Some(format!("rust-analyzer loaded, {} packages", progress)), | ||
752 | }), | ||
753 | ), | ||
754 | } | ||
755 | } | ||
756 | |||
757 | fn send_startup_progress_notif(sender: &Sender<Message>, work_done_progress: WorkDoneProgress) { | ||
758 | let notif = notification_new::<req::Progress>(req::ProgressParams { | ||
759 | token: req::ProgressToken::String("rustAnalyzer/startup".into()), | ||
760 | value: req::ProgressParamsValue::WorkDone(work_done_progress), | ||
761 | }); | ||
762 | sender.send(notif.into()).unwrap(); | ||
763 | } | ||
764 | |||
706 | struct PoolDispatcher<'a> { | 765 | struct PoolDispatcher<'a> { |
707 | req: Option<Request>, | 766 | req: Option<Request>, |
708 | pool: &'a ThreadPool, | 767 | pool: &'a ThreadPool, |