aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src/main_loop.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop.rs')
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs44
1 files changed, 43 insertions, 1 deletions
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index dda318e43..af1a487de 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -10,6 +10,7 @@ use std::{error::Error, fmt, panic, path::PathBuf, sync::Arc, time::Instant};
10use crossbeam_channel::{select, unbounded, RecvError, Sender}; 10use crossbeam_channel::{select, unbounded, RecvError, Sender};
11use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; 11use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response};
12use lsp_types::{ClientCapabilities, NumberOrString}; 12use lsp_types::{ClientCapabilities, NumberOrString};
13use ra_cargo_watch::{CheckOptions, CheckTask};
13use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId}; 14use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId};
14use ra_prof::profile; 15use ra_prof::profile;
15use ra_vfs::{VfsTask, Watch}; 16use ra_vfs::{VfsTask, Watch};
@@ -126,6 +127,12 @@ pub fn main_loop(
126 .and_then(|it| it.line_folding_only) 127 .and_then(|it| it.line_folding_only)
127 .unwrap_or(false), 128 .unwrap_or(false),
128 max_inlay_hint_length: config.max_inlay_hint_length, 129 max_inlay_hint_length: config.max_inlay_hint_length,
130 cargo_watch: CheckOptions {
131 enable: config.cargo_watch_enable,
132 args: config.cargo_watch_args,
133 command: config.cargo_watch_command,
134 all_targets: config.cargo_watch_all_targets,
135 },
129 } 136 }
130 }; 137 };
131 138
@@ -176,7 +183,11 @@ pub fn main_loop(
176 Ok(task) => Event::Vfs(task), 183 Ok(task) => Event::Vfs(task),
177 Err(RecvError) => Err("vfs died")?, 184 Err(RecvError) => Err("vfs died")?,
178 }, 185 },
179 recv(libdata_receiver) -> data => Event::Lib(data.unwrap()) 186 recv(libdata_receiver) -> data => Event::Lib(data.unwrap()),
187 recv(world_state.check_watcher.task_recv) -> task => match task {
188 Ok(task) => Event::CheckWatcher(task),
189 Err(RecvError) => Err("check watcher died")?,
190 }
180 }; 191 };
181 if let Event::Msg(Message::Request(req)) = &event { 192 if let Event::Msg(Message::Request(req)) = &event {
182 if connection.handle_shutdown(&req)? { 193 if connection.handle_shutdown(&req)? {
@@ -222,6 +233,7 @@ enum Event {
222 Task(Task), 233 Task(Task),
223 Vfs(VfsTask), 234 Vfs(VfsTask),
224 Lib(LibraryData), 235 Lib(LibraryData),
236 CheckWatcher(CheckTask),
225} 237}
226 238
227impl fmt::Debug for Event { 239impl fmt::Debug for Event {
@@ -259,6 +271,7 @@ impl fmt::Debug for Event {
259 Event::Task(it) => fmt::Debug::fmt(it, f), 271 Event::Task(it) => fmt::Debug::fmt(it, f),
260 Event::Vfs(it) => fmt::Debug::fmt(it, f), 272 Event::Vfs(it) => fmt::Debug::fmt(it, f),
261 Event::Lib(it) => fmt::Debug::fmt(it, f), 273 Event::Lib(it) => fmt::Debug::fmt(it, f),
274 Event::CheckWatcher(it) => fmt::Debug::fmt(it, f),
262 } 275 }
263 } 276 }
264} 277}
@@ -318,6 +331,28 @@ fn loop_turn(
318 world_state.maybe_collect_garbage(); 331 world_state.maybe_collect_garbage();
319 loop_state.in_flight_libraries -= 1; 332 loop_state.in_flight_libraries -= 1;
320 } 333 }
334 Event::CheckWatcher(task) => match task {
335 CheckTask::Update(uri) => {
336 // We manually send a diagnostic update when the watcher asks
337 // us to, to avoid the issue of having to change the file to
338 // receive updated diagnostics.
339 let path = uri.to_file_path().map_err(|()| format!("invalid uri: {}", uri))?;
340 if let Some(file_id) = world_state.vfs.read().path2file(&path) {
341 let params =
342 handlers::publish_diagnostics(&world_state.snapshot(), FileId(file_id.0))?;
343 let not = notification_new::<req::PublishDiagnostics>(params);
344 task_sender.send(Task::Notify(not)).unwrap();
345 }
346 }
347 CheckTask::Status(progress) => {
348 let params = req::ProgressParams {
349 token: req::ProgressToken::String("rustAnalyzer/cargoWatcher".to_string()),
350 value: req::ProgressParamsValue::WorkDone(progress),
351 };
352 let not = notification_new::<req::Progress>(params);
353 task_sender.send(Task::Notify(not)).unwrap();
354 }
355 },
321 Event::Msg(msg) => match msg { 356 Event::Msg(msg) => match msg {
322 Message::Request(req) => on_request( 357 Message::Request(req) => on_request(
323 world_state, 358 world_state,
@@ -517,6 +552,13 @@ fn on_notification(
517 } 552 }
518 Err(not) => not, 553 Err(not) => not,
519 }; 554 };
555 let not = match notification_cast::<req::DidSaveTextDocument>(not) {
556 Ok(_params) => {
557 state.check_watcher.update();
558 return Ok(());
559 }
560 Err(not) => not,
561 };
520 let not = match notification_cast::<req::DidCloseTextDocument>(not) { 562 let not = match notification_cast::<req::DidCloseTextDocument>(not) {
521 Ok(params) => { 563 Ok(params) => {
522 let uri = params.text_document.uri; 564 let uri = params.text_document.uri;