about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/config.rs17
-rw-r--r--crates/rust-analyzer/src/handlers.rs9
-rw-r--r--crates/rust-analyzer/src/main_loop.rs20
-rw-r--r--crates/rust-analyzer/tests/slow-tests/support.rs8
4 files changed, 28 insertions, 26 deletions
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 27445d1f712..835bc785c4e 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -27,7 +27,7 @@ use project_model::{
 };
 use rustc_hash::{FxHashMap, FxHashSet};
 use serde::{de::DeserializeOwned, Deserialize};
-use vfs::AbsPathBuf;
+use vfs::{AbsPath, AbsPathBuf};
 
 use crate::{
     caps::completion_item_edit_resolve,
@@ -535,8 +535,9 @@ impl Default for ConfigData {
 
 #[derive(Debug, Clone)]
 pub struct Config {
-    pub discovered_projects: Option<Vec<ProjectManifest>>,
-    pub workspace_roots: Vec<AbsPathBuf>,
+    discovered_projects: Option<Vec<ProjectManifest>>,
+    /// The workspace roots as registered by the LSP client
+    workspace_roots: Vec<AbsPathBuf>,
     caps: lsp_types::ClientCapabilities,
     root_path: AbsPathBuf,
     data: ConfigData,
@@ -758,6 +759,16 @@ impl Config {
         self.discovered_projects = Some(discovered);
     }
 
+    pub fn remove_workspace(&mut self, path: &AbsPath) {
+        if let Some(position) = self.workspace_roots.iter().position(|it| it == path) {
+            self.workspace_roots.remove(position);
+        }
+    }
+
+    pub fn add_workspaces(&mut self, paths: impl Iterator<Item = AbsPathBuf>) {
+        self.workspace_roots.extend(paths);
+    }
+
     pub fn update(&mut self, mut json: serde_json::Value) -> Result<(), ConfigUpdateError> {
         tracing::info!("updating config from JSON: {:#}", json);
         if json.is_null() || json.as_object().map_or(false, |it| it.is_empty()) {
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 54df01580a6..bcc3eed4ff9 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -777,14 +777,7 @@ pub(crate) fn handle_runnables(
             }
         }
         None => {
-            if !snap.config.linked_projects().is_empty()
-                || !snap
-                    .config
-                    .discovered_projects
-                    .as_ref()
-                    .map(|projects| projects.is_empty())
-                    .unwrap_or(true)
-            {
+            if !snap.config.linked_projects().is_empty() {
                 res.push(lsp_ext::Runnable {
                     label: "cargo check --workspace".to_string(),
                     location: None,
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index f9930fb2599..afbc2bb6c21 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -908,8 +908,10 @@ impl GlobalState {
                     // Re-fetch workspaces if a workspace related file has changed
                     if let Some(abs_path) = vfs_path.as_path() {
                         if reload::should_refresh_for_change(abs_path, ChangeKind::Modify) {
-                            this.fetch_workspaces_queue
-                                .request_op(format!("DidSaveTextDocument {}", abs_path.display()), ());
+                            this.fetch_workspaces_queue.request_op(
+                                format!("DidSaveTextDocument {}", abs_path.display()),
+                                (),
+                            );
                         }
                     }
 
@@ -972,8 +974,7 @@ impl GlobalState {
                 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);
+                    config.remove_workspace(&path);
                 }
 
                 let added = params
@@ -982,11 +983,12 @@ impl GlobalState {
                     .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(), ())
-                    }
+                config.add_workspaces(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(())
             })?
diff --git a/crates/rust-analyzer/tests/slow-tests/support.rs b/crates/rust-analyzer/tests/slow-tests/support.rs
index df62dcd7ddc..f3481914ed1 100644
--- a/crates/rust-analyzer/tests/slow-tests/support.rs
+++ b/crates/rust-analyzer/tests/slow-tests/support.rs
@@ -101,10 +101,6 @@ impl<'a> Project<'a> {
         if roots.is_empty() {
             roots.push(tmp_dir_path.clone());
         }
-        let discovered_projects = roots
-            .into_iter()
-            .map(|it| ProjectManifest::discover_single(&it).unwrap())
-            .collect::<Vec<_>>();
 
         let mut config = Config::new(
             tmp_dir_path,
@@ -144,10 +140,10 @@ impl<'a> Project<'a> {
                 })),
                 ..Default::default()
             },
-            Vec::new(),
+            roots,
         );
-        config.discovered_projects = Some(discovered_projects);
         config.update(self.config).expect("invalid config");
+        config.rediscover_workspaces();
 
         Server::new(tmp_dir, config)
     }