lsp: Remove Attach enum, default to Shared behaviour (#35248)

Piotr Osiewicz created

This should be a no-op PR, behavior-wise.

Release Notes:

- N/A

Change summary

crates/language/src/language.rs                 | 29 --------
crates/project/src/lsp_store.rs                 | 63 ++----------------
crates/project/src/manifest_tree/server_tree.rs | 23 ++----
3 files changed, 14 insertions(+), 101 deletions(-)

Detailed changes

crates/language/src/language.rs 🔗

@@ -166,7 +166,6 @@ pub struct CachedLspAdapter {
     pub reinstall_attempt_count: AtomicU64,
     cached_binary: futures::lock::Mutex<Option<LanguageServerBinary>>,
     manifest_name: OnceLock<Option<ManifestName>>,
-    attach_kind: OnceLock<Attach>,
 }
 
 impl Debug for CachedLspAdapter {
@@ -202,7 +201,6 @@ impl CachedLspAdapter {
             adapter,
             cached_binary: Default::default(),
             reinstall_attempt_count: AtomicU64::new(0),
-            attach_kind: Default::default(),
             manifest_name: Default::default(),
         })
     }
@@ -288,29 +286,6 @@ impl CachedLspAdapter {
             .get_or_init(|| self.adapter.manifest_name())
             .clone()
     }
-    pub fn attach_kind(&self) -> Attach {
-        *self.attach_kind.get_or_init(|| self.adapter.attach_kind())
-    }
-}
-
-#[derive(Clone, Copy, Debug, PartialEq)]
-pub enum Attach {
-    /// Create a single language server instance per subproject root.
-    InstancePerRoot,
-    /// Use one shared language server instance for all subprojects within a project.
-    Shared,
-}
-
-impl Attach {
-    pub fn root_path(
-        &self,
-        root_subproject_path: (WorktreeId, Arc<Path>),
-    ) -> (WorktreeId, Arc<Path>) {
-        match self {
-            Attach::InstancePerRoot => root_subproject_path,
-            Attach::Shared => (root_subproject_path.0, Arc::from(Path::new(""))),
-        }
-    }
 }
 
 /// Determines what gets sent out as a workspace folders content
@@ -611,10 +586,6 @@ pub trait LspAdapter: 'static + Send + Sync {
         Ok(original)
     }
 
-    fn attach_kind(&self) -> Attach {
-        Attach::Shared
-    }
-
     /// Determines whether a language server supports workspace folders.
     ///
     /// And does not trip over itself in the process.

crates/project/src/lsp_store.rs 🔗

@@ -2425,36 +2425,12 @@ impl LocalLspStore {
                 let server_id = server_node.server_id_or_init(
                     |LaunchDisposition {
                          server_name,
-                         attach,
+
                          path,
                          settings,
                      }| {
-                        let server_id = match attach {
-                           language::Attach::InstancePerRoot => {
-                               // todo: handle instance per root proper.
-                               if let Some(server_ids) = self
-                                   .language_server_ids
-                                   .get(&(worktree_id, server_name.clone()))
-                               {
-                                   server_ids.iter().cloned().next().unwrap()
-                               } else {
-                                   let language_name = language.name();
-                                   let adapter = self.languages
-                                       .lsp_adapters(&language_name)
-                                       .into_iter()
-                                       .find(|adapter| &adapter.name() == server_name)
-                                       .expect("To find LSP adapter");
-                                   let server_id = self.start_language_server(
-                                       &worktree,
-                                       delegate.clone(),
-                                       adapter,
-                                       settings,
-                                       cx,
-                                   );
-                                   server_id
-                               }
-                           }
-                           language::Attach::Shared => {
+                        let server_id =
+                           {
                                let uri = Url::from_file_path(
                                    worktree.read(cx).abs_path().join(&path.path),
                                );
@@ -2489,7 +2465,7 @@ impl LocalLspStore {
                                } else {
                                    unreachable!("Language server ID should be available, as it's registered on demand")
                                }
-                           }
+
                         };
                         let lsp_store = self.weak.clone();
                         let server_name = server_node.name();
@@ -4705,35 +4681,11 @@ impl LspStore {
                                 let server_id = node.server_id_or_init(
                                     |LaunchDisposition {
                                          server_name,
-                                         attach,
+
                                          path,
                                          settings,
-                                     }| match attach {
-                                        language::Attach::InstancePerRoot => {
-                                            // todo: handle instance per root proper.
-                                            if let Some(server_ids) = local
-                                                .language_server_ids
-                                                .get(&(worktree_id, server_name.clone()))
-                                            {
-                                                server_ids.iter().cloned().next().unwrap()
-                                            } else {
-                                                let adapter = local
-                                                    .languages
-                                                    .lsp_adapters(&language)
-                                                    .into_iter()
-                                                    .find(|adapter| &adapter.name() == server_name)
-                                                    .expect("To find LSP adapter");
-                                                let server_id = local.start_language_server(
-                                                    &worktree,
-                                                    delegate.clone(),
-                                                    adapter,
-                                                    settings,
-                                                    cx,
-                                                );
-                                                server_id
-                                            }
-                                        }
-                                        language::Attach::Shared => {
+                                     }|
+                                         {
                                             let uri = Url::from_file_path(
                                                 worktree.read(cx).abs_path().join(&path.path),
                                             );
@@ -4762,7 +4714,6 @@ impl LspStore {
                                             }
                                             server_id
                                         }
-                                    },
                                 );
 
                                 if let Some(language_server_id) = server_id {

crates/project/src/manifest_tree/server_tree.rs 🔗

@@ -13,10 +13,10 @@ use std::{
     sync::{Arc, Weak},
 };
 
-use collections::{HashMap, IndexMap};
+use collections::IndexMap;
 use gpui::{App, AppContext as _, Entity, Subscription};
 use language::{
-    Attach, CachedLspAdapter, LanguageName, LanguageRegistry, ManifestDelegate,
+    CachedLspAdapter, LanguageName, LanguageRegistry, ManifestDelegate,
     language_settings::AllLanguageSettings,
 };
 use lsp::LanguageServerName;
@@ -38,7 +38,6 @@ pub(crate) struct ServersForWorktree {
 pub struct LanguageServerTree {
     manifest_tree: Entity<ManifestTree>,
     pub(crate) instances: BTreeMap<WorktreeId, ServersForWorktree>,
-    attach_kind_cache: HashMap<LanguageServerName, Attach>,
     languages: Arc<LanguageRegistry>,
     _subscriptions: Subscription,
 }
@@ -53,7 +52,6 @@ pub struct LanguageServerTreeNode(Weak<InnerTreeNode>);
 #[derive(Debug)]
 pub(crate) struct LaunchDisposition<'a> {
     pub(crate) server_name: &'a LanguageServerName,
-    pub(crate) attach: Attach,
     pub(crate) path: ProjectPath,
     pub(crate) settings: Arc<LspSettings>,
 }
@@ -62,7 +60,6 @@ impl<'a> From<&'a InnerTreeNode> for LaunchDisposition<'a> {
     fn from(value: &'a InnerTreeNode) -> Self {
         LaunchDisposition {
             server_name: &value.name,
-            attach: value.attach,
             path: value.path.clone(),
             settings: value.settings.clone(),
         }
@@ -105,7 +102,6 @@ impl From<Weak<InnerTreeNode>> for LanguageServerTreeNode {
 pub struct InnerTreeNode {
     id: OnceLock<LanguageServerId>,
     name: LanguageServerName,
-    attach: Attach,
     path: ProjectPath,
     settings: Arc<LspSettings>,
 }
@@ -113,14 +109,12 @@ pub struct InnerTreeNode {
 impl InnerTreeNode {
     fn new(
         name: LanguageServerName,
-        attach: Attach,
         path: ProjectPath,
         settings: impl Into<Arc<LspSettings>>,
     ) -> Self {
         InnerTreeNode {
             id: Default::default(),
             name,
-            attach,
             path,
             settings: settings.into(),
         }
@@ -130,8 +124,11 @@ impl InnerTreeNode {
 /// Determines how the list of adapters to query should be constructed.
 pub(crate) enum AdapterQuery<'a> {
     /// Search for roots of all adapters associated with a given language name.
+    /// Layman: Look for all project roots along the queried path that have any
+    /// language server associated with this language running.
     Language(&'a LanguageName),
     /// Search for roots of adapter with a given name.
+    /// Layman: Look for all project roots along the queried path that have this server running.
     Adapter(&'a LanguageServerName),
 }
 
@@ -147,7 +144,7 @@ impl LanguageServerTree {
             }),
             manifest_tree,
             instances: Default::default(),
-            attach_kind_cache: Default::default(),
+
             languages,
         })
     }
@@ -223,7 +220,6 @@ impl LanguageServerTree {
                     .and_then(|name| roots.get(&name))
                     .cloned()
                     .unwrap_or_else(|| root_path.clone());
-                let attach = adapter.attach_kind();
 
                 let inner_node = self
                     .instances
@@ -237,7 +233,6 @@ impl LanguageServerTree {
                     (
                         Arc::new(InnerTreeNode::new(
                             adapter.name(),
-                            attach,
                             root_path.clone(),
                             settings.clone(),
                         )),
@@ -379,7 +374,6 @@ pub(crate) struct ServerTreeRebase<'a> {
 impl<'tree> ServerTreeRebase<'tree> {
     fn new(new_tree: &'tree mut LanguageServerTree) -> Self {
         let old_contents = std::mem::take(&mut new_tree.instances);
-        new_tree.attach_kind_cache.clear();
         let all_server_ids = old_contents
             .values()
             .flat_map(|nodes| {
@@ -446,10 +440,7 @@ impl<'tree> ServerTreeRebase<'tree> {
                     .get(&disposition.path.worktree_id)
                     .and_then(|worktree_nodes| worktree_nodes.roots.get(&disposition.path.path))
                     .and_then(|roots| roots.get(&disposition.name))
-                    .filter(|(old_node, _)| {
-                        disposition.attach == old_node.attach
-                            && disposition.settings == old_node.settings
-                    })
+                    .filter(|(old_node, _)| disposition.settings == old_node.settings)
                 else {
                     return Some(node);
                 };