summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs')
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs61
1 files changed, 42 insertions, 19 deletions
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
index 0bc940dfe..d1e38b33c 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
@@ -14,7 +14,7 @@ use ide_db::base_db::{SourceDatabaseExt, VfsPath};
use itertools::Itertools;
use lsp_server::{Connection, Notification, Request};
use lsp_types::notification::Notification as _;
-use vfs::{ChangeKind, FileId};
+use vfs::{AbsPathBuf, ChangeKind, FileId};
use crate::{
config::Config,
@@ -287,8 +287,10 @@ impl GlobalState {
|| self.fetch_build_data_queue.op_requested());
if became_quiescent {
- // Project has loaded properly, kick off initial flycheck
- self.flycheck.iter().for_each(FlycheckHandle::restart);
+ if self.config.check_on_save() {
+ // Project has loaded properly, kick off initial flycheck
+ self.flycheck.iter().for_each(FlycheckHandle::restart);
+ }
if self.config.prefill_caches() {
self.prime_caches_queue.request_op("became quiescent".to_string());
}
@@ -305,13 +307,18 @@ impl GlobalState {
if self.config.code_lens_refresh() {
self.send_request::<lsp_types::request::CodeLensRefresh>((), |_, _| ());
}
- }
- if !was_quiescent || state_changed || memdocs_added_or_removed {
- if self.config.publish_diagnostics() {
- self.update_diagnostics()
+ // Refresh inlay hints if the client supports it.
+ if self.config.inlay_hints_refresh() {
+ self.send_request::<lsp_types::request::InlayHintRefreshRequest>((), |_, _| ());
}
}
+
+ if (!was_quiescent || state_changed || memdocs_added_or_removed)
+ && self.config.publish_diagnostics()
+ {
+ self.update_diagnostics()
+ }
}
if let Some(diagnostic_changes) = self.diagnostics.take_changes() {
@@ -604,8 +611,8 @@ impl GlobalState {
Ok(())
});
- if let RequestDispatcher { req: Some(req), global_state: this } = &mut dispatcher {
- if this.shutdown_requested {
+ match &mut dispatcher {
+ RequestDispatcher { req: Some(req), global_state: this } if this.shutdown_requested => {
this.respond(lsp_server::Response::new_err(
req.id.clone(),
lsp_server::ErrorCode::InvalidRequest as i32,
@@ -613,16 +620,7 @@ impl GlobalState {
));
return;
}
-
- // Avoid flashing a bunch of unresolved references during initial load.
- if this.workspaces.is_empty() && !this.is_quiescent() {
- this.respond(lsp_server::Response::new_err(
- req.id.clone(),
- lsp_server::ErrorCode::ContentModified as i32,
- "waiting for cargo metadata or cargo check".to_owned(),
- ));
- return;
- }
+ _ => (),
}
dispatcher
@@ -833,6 +831,7 @@ impl GlobalState {
let vfs = &mut this.vfs.write().0;
let file_id = vfs.file_id(&path).unwrap();
let text = apply_document_changes(
+ this.config.position_encoding(),
|| std::str::from_utf8(vfs.file_contents(file_id)).unwrap().into(),
params.content_changes,
);
@@ -935,6 +934,30 @@ impl GlobalState {
Ok(())
})?
+ .on::<lsp_types::notification::DidChangeWorkspaceFolders>(|this, params| {
+ let config = Arc::make_mut(&mut this.config);
+
+ for workspace in params.event.removed {
+ let Ok(path) = workspace.uri.to_file_path() else { continue };
+ let Ok(path) = AbsPathBuf::try_from(path) else { continue };
+ let Some(position) = config.workspace_roots.iter().position(|it| it == &path) else { continue };
+ config.workspace_roots.remove(position);
+ }
+
+ let added = params
+ .event
+ .added
+ .into_iter()
+ .filter_map(|it| it.uri.to_file_path().ok())
+ .filter_map(|it| AbsPathBuf::try_from(it).ok());
+ config.workspace_roots.extend(added);
+ if !config.has_linked_projects() && config.detached_files().is_empty() {
+ config.rediscover_workspaces();
+ this.fetch_workspaces_queue.request_op("client workspaces changed".to_string())
+ }
+
+ Ok(())
+ })?
.on::<lsp_types::notification::DidChangeWatchedFiles>(|this, params| {
for change in params.changes {
if let Ok(path) = from_proto::abs_path(&change.uri) {