aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer/src/main_loop
diff options
context:
space:
mode:
Diffstat (limited to 'crates/rust-analyzer/src/main_loop')
-rw-r--r--crates/rust-analyzer/src/main_loop/lsp_utils.rs8
-rw-r--r--crates/rust-analyzer/src/main_loop/progress.rs129
2 files changed, 7 insertions, 130 deletions
diff --git a/crates/rust-analyzer/src/main_loop/lsp_utils.rs b/crates/rust-analyzer/src/main_loop/lsp_utils.rs
index fc008cba5..c79022797 100644
--- a/crates/rust-analyzer/src/main_loop/lsp_utils.rs
+++ b/crates/rust-analyzer/src/main_loop/lsp_utils.rs
@@ -1,10 +1,16 @@
1//! Utilities for LSP-related boilerplate code.
2
1use crossbeam_channel::Sender; 3use crossbeam_channel::Sender;
2use lsp_server::{Message, Notification, Request, RequestId}; 4use lsp_server::{Message, Notification, Request, RequestId};
3use ra_db::Canceled; 5use ra_db::Canceled;
4use serde::{de::DeserializeOwned, Serialize}; 6use serde::{de::DeserializeOwned, Serialize};
5use std::error::Error; 7use std::error::Error;
6 8
7pub fn show_message(typ: lsp_types::MessageType, message: impl Into<String>, sender: &Sender<Message>) { 9pub fn show_message(
10 typ: lsp_types::MessageType,
11 message: impl Into<String>,
12 sender: &Sender<Message>,
13) {
8 let message = message.into(); 14 let message = message.into();
9 let params = lsp_types::ShowMessageParams { typ, message }; 15 let params = lsp_types::ShowMessageParams { typ, message };
10 let not = notification_new::<lsp_types::notification::ShowMessage>(params); 16 let not = notification_new::<lsp_types::notification::ShowMessage>(params);
diff --git a/crates/rust-analyzer/src/main_loop/progress.rs b/crates/rust-analyzer/src/main_loop/progress.rs
deleted file mode 100644
index 610e026ca..000000000
--- a/crates/rust-analyzer/src/main_loop/progress.rs
+++ /dev/null
@@ -1,129 +0,0 @@
1use super::lsp_utils::{notification_new, request_new};
2use crossbeam_channel::Sender;
3use lsp_server::{Message, RequestId};
4use lsp_types::{
5 WorkDoneProgress, WorkDoneProgressBegin, WorkDoneProgressCreateParams, WorkDoneProgressEnd,
6 WorkDoneProgressReport,
7};
8
9const PRIME_CACHES_PROGRESS_TOKEN: &str = "rustAnalyzer/primeCaches";
10const WORKSPACE_ANALYSIS_PROGRESS_TOKEN: &str = "rustAnalyzer/workspaceAnalysis";
11
12#[derive(Debug)]
13pub(crate) struct PrimeCachesProgressNotifier(ProgressNotifier);
14
15impl Drop for PrimeCachesProgressNotifier {
16 fn drop(&mut self) {
17 self.0.end("done priming caches".to_owned());
18 }
19}
20
21impl PrimeCachesProgressNotifier {
22 pub(crate) fn begin(sender: Sender<Message>, req_id: RequestId, total: usize) -> Self {
23 let me = Self(ProgressNotifier {
24 sender,
25 processed: 0,
26 total,
27 token: PRIME_CACHES_PROGRESS_TOKEN,
28 label: "priming caches",
29 });
30 me.0.begin(req_id);
31 me
32 }
33
34 pub(crate) fn report(&mut self, processed: usize) -> IsDone {
35 self.0.report(processed)
36 }
37}
38
39#[derive(Debug)]
40pub(crate) struct WorkspaceAnalysisProgressNotifier(ProgressNotifier);
41
42impl Drop for WorkspaceAnalysisProgressNotifier {
43 fn drop(&mut self) {
44 self.0.end("done analyzing workspace".to_owned());
45 }
46}
47
48impl WorkspaceAnalysisProgressNotifier {
49 pub(crate) fn begin(sender: Sender<Message>, req_id: RequestId, total: usize) -> Self {
50 let me = Self(ProgressNotifier {
51 sender,
52 total,
53 processed: 0,
54 token: WORKSPACE_ANALYSIS_PROGRESS_TOKEN,
55 label: "analyzing packages",
56 });
57 me.0.begin(req_id);
58 me
59 }
60
61 pub(crate) fn report(&mut self, processed: usize) -> IsDone {
62 self.0.report(processed)
63 }
64}
65
66#[derive(Debug, PartialEq, Eq)]
67pub struct IsDone(pub bool);
68
69#[derive(Debug)]
70struct ProgressNotifier {
71 sender: Sender<Message>,
72 token: &'static str,
73 label: &'static str,
74 processed: usize,
75 total: usize,
76}
77
78impl ProgressNotifier {
79 fn begin(&self, req_id: RequestId) {
80 let create_req = request_new::<lsp_types::request::WorkDoneProgressCreate>(
81 req_id,
82 WorkDoneProgressCreateParams {
83 token: lsp_types::ProgressToken::String(self.token.to_owned()),
84 },
85 );
86 self.sender.send(create_req.into()).unwrap();
87 self.send_notification(WorkDoneProgress::Begin(WorkDoneProgressBegin {
88 cancellable: None,
89 title: "rust-analyzer".to_owned(),
90 percentage: Some(self.percentage()),
91 message: Some(self.create_progress_message()),
92 }));
93 }
94
95 fn report(&mut self, processed: usize) -> IsDone {
96 if self.processed != processed {
97 self.processed = processed;
98
99 self.send_notification(WorkDoneProgress::Report(WorkDoneProgressReport {
100 cancellable: None,
101 percentage: Some(self.percentage()),
102 message: Some(self.create_progress_message()),
103 }));
104 }
105 IsDone(processed >= self.total)
106 }
107
108 fn end(&mut self, message: String) {
109 self.send_notification(WorkDoneProgress::End(WorkDoneProgressEnd {
110 message: Some(message),
111 }));
112 }
113
114 fn send_notification(&self, progress: WorkDoneProgress) {
115 let notif = notification_new::<lsp_types::notification::Progress>(lsp_types::ProgressParams {
116 token: lsp_types::ProgressToken::String(self.token.to_owned()),
117 value: lsp_types::ProgressParamsValue::WorkDone(progress),
118 });
119 self.sender.send(notif.into()).unwrap();
120 }
121
122 fn create_progress_message(&self) -> String {
123 format!("{} ({}/{})", self.label, self.processed, self.total)
124 }
125
126 fn percentage(&self) -> f64 {
127 (100 * self.processed) as f64 / self.total as f64
128 }
129}