aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/rust-analyzer/src/config.rs2
-rw-r--r--crates/rust-analyzer/src/global_state.rs2
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs18
-rw-r--r--crates/rust-analyzer/src/main_loop.rs56
-rw-r--r--crates/rust-analyzer/src/reload.rs2
-rw-r--r--crates/rust-analyzer/tests/heavy_tests/support.rs17
6 files changed, 86 insertions, 11 deletions
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 6c311648a..21acfe644 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -130,6 +130,7 @@ pub struct ClientCapsConfig {
130 pub code_action_group: bool, 130 pub code_action_group: bool,
131 pub resolve_code_action: bool, 131 pub resolve_code_action: bool,
132 pub hover_actions: bool, 132 pub hover_actions: bool,
133 pub status_notification: bool,
133} 134}
134 135
135impl Config { 136impl Config {
@@ -365,6 +366,7 @@ impl Config {
365 self.client_caps.code_action_group = get_bool("codeActionGroup"); 366 self.client_caps.code_action_group = get_bool("codeActionGroup");
366 self.client_caps.resolve_code_action = get_bool("resolveCodeAction"); 367 self.client_caps.resolve_code_action = get_bool("resolveCodeAction");
367 self.client_caps.hover_actions = get_bool("hoverActions"); 368 self.client_caps.hover_actions = get_bool("hoverActions");
369 self.client_caps.status_notification = get_bool("statusNotification");
368 } 370 }
369 } 371 }
370} 372}
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index b7b4edf66..640b3959d 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -31,6 +31,8 @@ use crate::{
31pub(crate) enum Status { 31pub(crate) enum Status {
32 Loading, 32 Loading,
33 Ready, 33 Ready,
34 Invalid,
35 NeedsReload,
34} 36}
35 37
36impl Default for Status { 38impl Default for Status {
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs
index 82207bbb8..d225ad5ff 100644
--- a/crates/rust-analyzer/src/lsp_ext.rs
+++ b/crates/rust-analyzer/src/lsp_ext.rs
@@ -3,7 +3,7 @@
3use std::{collections::HashMap, path::PathBuf}; 3use std::{collections::HashMap, path::PathBuf};
4 4
5use lsp_types::request::Request; 5use lsp_types::request::Request;
6use lsp_types::{Position, Range, TextDocumentIdentifier}; 6use lsp_types::{notification::Notification, Position, Range, TextDocumentIdentifier};
7use serde::{Deserialize, Serialize}; 7use serde::{Deserialize, Serialize};
8 8
9pub enum AnalyzerStatus {} 9pub enum AnalyzerStatus {}
@@ -208,6 +208,22 @@ pub struct SsrParams {
208 pub parse_only: bool, 208 pub parse_only: bool,
209} 209}
210 210
211pub enum StatusNotification {}
212
213#[serde(rename_all = "camelCase")]
214#[derive(Serialize, Deserialize)]
215pub enum Status {
216 Loading,
217 Ready,
218 NeedsReload,
219 Invalid,
220}
221
222impl Notification for StatusNotification {
223 type Params = Status;
224 const METHOD: &'static str = "rust-analyzer/status";
225}
226
211pub enum CodeActionRequest {} 227pub enum CodeActionRequest {}
212 228
213impl Request for CodeActionRequest { 229impl Request for CodeActionRequest {
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index e03038b25..d4d18a808 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -111,6 +111,35 @@ impl GlobalState {
111 } 111 }
112 112
113 fn run(mut self, inbox: Receiver<lsp_server::Message>) -> Result<()> { 113 fn run(mut self, inbox: Receiver<lsp_server::Message>) -> Result<()> {
114 let registration_options = lsp_types::TextDocumentRegistrationOptions {
115 document_selector: Some(vec![
116 lsp_types::DocumentFilter {
117 language: None,
118 scheme: None,
119 pattern: Some("**/*.rs".into()),
120 },
121 lsp_types::DocumentFilter {
122 language: None,
123 scheme: None,
124 pattern: Some("**/Cargo.toml".into()),
125 },
126 lsp_types::DocumentFilter {
127 language: None,
128 scheme: None,
129 pattern: Some("**/Cargo.lock".into()),
130 },
131 ]),
132 };
133 let registration = lsp_types::Registration {
134 id: "textDocument/didSave".to_string(),
135 method: "textDocument/didSave".to_string(),
136 register_options: Some(serde_json::to_value(registration_options).unwrap()),
137 };
138 self.send_request::<lsp_types::request::RegisterCapability>(
139 lsp_types::RegistrationParams { registrations: vec![registration] },
140 |_, _| (),
141 );
142
114 self.reload(); 143 self.reload();
115 144
116 while let Some(event) = self.next_event(&inbox) { 145 while let Some(event) = self.next_event(&inbox) {
@@ -169,16 +198,16 @@ impl GlobalState {
169 } 198 }
170 vfs::loader::Message::Progress { n_total, n_done } => { 199 vfs::loader::Message::Progress { n_total, n_done } => {
171 if n_total == 0 { 200 if n_total == 0 {
172 self.status = Status::Ready; 201 self.transition(Status::Invalid);
173 } else { 202 } else {
174 let state = if n_done == 0 { 203 let state = if n_done == 0 {
175 self.status = Status::Loading; 204 self.transition(Status::Loading);
176 Progress::Begin 205 Progress::Begin
177 } else if n_done < n_total { 206 } else if n_done < n_total {
178 Progress::Report 207 Progress::Report
179 } else { 208 } else {
180 assert_eq!(n_done, n_total); 209 assert_eq!(n_done, n_total);
181 self.status = Status::Ready; 210 self.transition(Status::Ready);
182 Progress::End 211 Progress::End
183 }; 212 };
184 self.report_progress( 213 self.report_progress(
@@ -274,6 +303,19 @@ impl GlobalState {
274 Ok(()) 303 Ok(())
275 } 304 }
276 305
306 fn transition(&mut self, new_status: Status) {
307 self.status = Status::Ready;
308 if self.config.client_caps.status_notification {
309 let lsp_status = match new_status {
310 Status::Loading => lsp_ext::Status::Loading,
311 Status::Ready => lsp_ext::Status::Ready,
312 Status::Invalid => lsp_ext::Status::Invalid,
313 Status::NeedsReload => lsp_ext::Status::NeedsReload,
314 };
315 self.send_notification::<lsp_ext::StatusNotification>(lsp_status);
316 }
317 }
318
277 fn on_request(&mut self, request_received: Instant, req: Request) -> Result<()> { 319 fn on_request(&mut self, request_received: Instant, req: Request) -> Result<()> {
278 self.register_request(&req, request_received); 320 self.register_request(&req, request_received);
279 321
@@ -383,10 +425,16 @@ impl GlobalState {
383 ); 425 );
384 Ok(()) 426 Ok(())
385 })? 427 })?
386 .on::<lsp_types::notification::DidSaveTextDocument>(|this, _params| { 428 .on::<lsp_types::notification::DidSaveTextDocument>(|this, params| {
387 if let Some(flycheck) = &this.flycheck { 429 if let Some(flycheck) = &this.flycheck {
388 flycheck.handle.update(); 430 flycheck.handle.update();
389 } 431 }
432 let uri = params.text_document.uri.as_str();
433 if uri.ends_with("Cargo.toml") || uri.ends_with("Cargo.lock") {
434 if matches!(this.status, Status::Ready | Status::Invalid) {
435 this.transition(Status::NeedsReload);
436 }
437 }
390 Ok(()) 438 Ok(())
391 })? 439 })?
392 .on::<lsp_types::notification::DidChangeConfiguration>(|this, _params| { 440 .on::<lsp_types::notification::DidChangeConfiguration>(|this, _params| {
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index 0c1fd1b8b..523b04b97 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -78,7 +78,7 @@ impl GlobalState {
78 .collect(), 78 .collect(),
79 }; 79 };
80 let registration = lsp_types::Registration { 80 let registration = lsp_types::Registration {
81 id: "file-watcher".to_string(), 81 id: "workspace/didChangeWatchedFiles".to_string(),
82 method: "workspace/didChangeWatchedFiles".to_string(), 82 method: "workspace/didChangeWatchedFiles".to_string(),
83 register_options: Some(serde_json::to_value(registration_options).unwrap()), 83 register_options: Some(serde_json::to_value(registration_options).unwrap()),
84 }; 84 };
diff --git a/crates/rust-analyzer/tests/heavy_tests/support.rs b/crates/rust-analyzer/tests/heavy_tests/support.rs
index 49f194f7e..7bf687794 100644
--- a/crates/rust-analyzer/tests/heavy_tests/support.rs
+++ b/crates/rust-analyzer/tests/heavy_tests/support.rs
@@ -176,12 +176,19 @@ impl Server {
176 while let Some(msg) = self.recv() { 176 while let Some(msg) = self.recv() {
177 match msg { 177 match msg {
178 Message::Request(req) => { 178 Message::Request(req) => {
179 if req.method != "window/workDoneProgress/create" 179 if req.method == "window/workDoneProgress/create" {
180 && !(req.method == "client/registerCapability" 180 continue;
181 && req.params.to_string().contains("workspace/didChangeWatchedFiles"))
182 {
183 panic!("unexpected request: {:?}", req)
184 } 181 }
182 if req.method == "client/registerCapability" {
183 let params = req.params.to_string();
184 if ["workspace/didChangeWatchedFiles", "textDocument/didSave"]
185 .iter()
186 .any(|&it| params.contains(it))
187 {
188 continue;
189 }
190 }
191 panic!("unexpected request: {:?}", req)
185 } 192 }
186 Message::Notification(_) => (), 193 Message::Notification(_) => (),
187 Message::Response(res) => { 194 Message::Response(res) => {