aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/main_loop.rs71
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
17use crossbeam_channel::{select, unbounded, RecvError, Sender}; 17use crossbeam_channel::{select, unbounded, RecvError, Sender};
18use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; 18use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response};
19use lsp_types::{ClientCapabilities, NumberOrString}; 19use lsp_types::{
20 ClientCapabilities, NumberOrString, WorkDoneProgress, WorkDoneProgressBegin,
21 WorkDoneProgressCreateParams, WorkDoneProgressEnd, WorkDoneProgressReport,
22};
20use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckTask}; 23use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckTask};
21use ra_ide::{Canceled, FileId, InlayHintsOptions, LibraryData, SourceRootId}; 24use ra_ide::{Canceled, FileId, InlayHintsOptions, LibraryData, SourceRootId};
22use ra_prof::profile; 25use 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
334impl LoopState { 338impl 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
706fn 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
757fn 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
706struct PoolDispatcher<'a> { 765struct PoolDispatcher<'a> {
707 req: Option<Request>, 766 req: Option<Request>,
708 pool: &'a ThreadPool, 767 pool: &'a ThreadPool,