Move all configuration of individual LSP servers to LspAdapter

Max Brunsfeld created

Change summary

crates/language/src/buffer.rs             |  3 
crates/language/src/language.rs           | 46 +++++++++++++-------
crates/project/src/project.rs             | 55 +++++++++++-------------
crates/server/src/rpc.rs                  |  1 
crates/zed/src/languages/rust.rs          |  8 +++
crates/zed/src/languages/rust/config.toml |  4 -
6 files changed, 65 insertions(+), 52 deletions(-)

Detailed changes

crates/language/src/buffer.rs 🔗

@@ -1,8 +1,7 @@
 pub use crate::{
     diagnostic_set::DiagnosticSet,
     highlight_map::{HighlightId, HighlightMap},
-    proto, BracketPair, Grammar, Language, LanguageConfig, LanguageRegistry, LanguageServerConfig,
-    PLAIN_TEXT,
+    proto, BracketPair, Grammar, Language, LanguageConfig, LanguageRegistry, PLAIN_TEXT,
 };
 use crate::{
     diagnostic_set::{DiagnosticEntry, DiagnosticGroup},

crates/language/src/language.rs 🔗

@@ -8,7 +8,7 @@ mod tests;
 
 use anyhow::{anyhow, Context, Result};
 use client::http::{self, HttpClient};
-use collections::{HashMap, HashSet};
+use collections::HashMap;
 use futures::{
     future::{BoxFuture, Shared},
     FutureExt, TryFutureExt,
@@ -52,7 +52,6 @@ lazy_static! {
             brackets: Default::default(),
             autoclose_before: Default::default(),
             line_comment: None,
-            language_server: Default::default(),
         },
         None,
     ));
@@ -100,6 +99,14 @@ pub trait LspAdapter: 'static + Send + Sync {
     fn initialization_options(&self) -> Option<Value> {
         None
     }
+
+    fn disk_based_diagnostic_sources(&self) -> &'static [&'static str] {
+        Default::default()
+    }
+
+    fn disk_based_diagnostics_progress_token(&self) -> Option<&'static str> {
+        None
+    }
 }
 
 #[derive(Clone, Debug, PartialEq, Eq)]
@@ -117,8 +124,6 @@ pub struct LanguageConfig {
     #[serde(default)]
     pub autoclose_before: String,
     pub line_comment: Option<String>,
-    #[serde(default)]
-    pub language_server: LanguageServerConfig,
 }
 
 impl Default for LanguageConfig {
@@ -129,22 +134,17 @@ impl Default for LanguageConfig {
             brackets: Default::default(),
             autoclose_before: Default::default(),
             line_comment: Default::default(),
-            language_server: Default::default(),
         }
     }
 }
 
-#[derive(Default, Deserialize)]
-pub struct LanguageServerConfig {
-    pub disk_based_diagnostic_sources: HashSet<String>,
-    pub disk_based_diagnostics_progress_token: Option<String>,
-}
-
 #[cfg(any(test, feature = "test-support"))]
 pub struct FakeLspAdapter {
     pub name: &'static str,
     pub capabilities: lsp::ServerCapabilities,
     pub initializer: Option<Box<dyn 'static + Send + Sync + Fn(&mut lsp::FakeLanguageServer)>>,
+    pub disk_based_diagnostics_progress_token: Option<&'static str>,
+    pub disk_based_diagnostics_sources: &'static [&'static str],
 }
 
 #[derive(Clone, Debug, Deserialize)]
@@ -500,15 +500,16 @@ impl Language {
         self.config.line_comment.as_deref()
     }
 
-    pub fn disk_based_diagnostic_sources(&self) -> &HashSet<String> {
-        &self.config.language_server.disk_based_diagnostic_sources
+    pub fn disk_based_diagnostic_sources(&self) -> &'static [&'static str] {
+        self.adapter.as_ref().map_or(&[] as &[_], |adapter| {
+            adapter.disk_based_diagnostic_sources()
+        })
     }
 
-    pub fn disk_based_diagnostics_progress_token(&self) -> Option<&String> {
-        self.config
-            .language_server
-            .disk_based_diagnostics_progress_token
+    pub fn disk_based_diagnostics_progress_token(&self) -> Option<&'static str> {
+        self.adapter
             .as_ref()
+            .and_then(|adapter| adapter.disk_based_diagnostics_progress_token())
     }
 
     pub fn process_diagnostics(&self, diagnostics: &mut lsp::PublishDiagnosticsParams) {
@@ -621,10 +622,13 @@ impl Default for FakeLspAdapter {
             name: "the-fake-language-server",
             capabilities: lsp::LanguageServer::full_capabilities(),
             initializer: None,
+            disk_based_diagnostics_progress_token: None,
+            disk_based_diagnostics_sources: &[],
         }
     }
 }
 
+#[cfg(any(test, feature = "test-support"))]
 impl LspAdapter for FakeLspAdapter {
     fn name(&self) -> LanguageServerName {
         LanguageServerName(self.name.into())
@@ -651,6 +655,14 @@ impl LspAdapter for FakeLspAdapter {
     }
 
     fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {}
+
+    fn disk_based_diagnostic_sources(&self) -> &'static [&'static str] {
+        self.disk_based_diagnostics_sources
+    }
+
+    fn disk_based_diagnostics_progress_token(&self) -> Option<&'static str> {
+        self.disk_based_diagnostics_progress_token
+    }
 }
 
 impl ToLspPosition for PointUtf16 {

crates/project/src/project.rs 🔗

@@ -1536,7 +1536,7 @@ impl Project {
 
         match event {
             LanguageServerEvent::WorkStart { token } => {
-                if Some(&token) == disk_diagnostics_token {
+                if Some(token.as_str()) == disk_diagnostics_token {
                     language_server_status.pending_diagnostic_updates += 1;
                     if language_server_status.pending_diagnostic_updates == 1 {
                         self.disk_based_diagnostics_started(cx);
@@ -1558,7 +1558,7 @@ impl Project {
                 }
             }
             LanguageServerEvent::WorkProgress { token, progress } => {
-                if Some(&token) != disk_diagnostics_token {
+                if Some(token.as_str()) != disk_diagnostics_token {
                     self.on_lsp_work_progress(
                         language_server_id,
                         token.clone(),
@@ -1578,7 +1578,7 @@ impl Project {
                 }
             }
             LanguageServerEvent::WorkEnd { token } => {
-                if Some(&token) == disk_diagnostics_token {
+                if Some(token.as_str()) == disk_diagnostics_token {
                     language_server_status.pending_diagnostic_updates -= 1;
                     if language_server_status.pending_diagnostic_updates == 0 {
                         self.disk_based_diagnostics_finished(cx);
@@ -1708,7 +1708,7 @@ impl Project {
     pub fn update_diagnostics(
         &mut self,
         params: lsp::PublishDiagnosticsParams,
-        disk_based_sources: &HashSet<String>,
+        disk_based_sources: &[&str],
         cx: &mut ModelContext<Self>,
     ) -> Result<()> {
         let abs_path = params
@@ -1751,8 +1751,9 @@ impl Project {
                 );
             } else {
                 let group_id = post_inc(&mut next_group_id);
-                let is_disk_based =
-                    source.map_or(false, |source| disk_based_sources.contains(source));
+                let is_disk_based = source.map_or(false, |source| {
+                    disk_based_sources.contains(&source.as_str())
+                });
 
                 sources_by_group_id.insert(group_id, source);
                 primary_diagnostic_group_ids
@@ -4606,8 +4607,8 @@ mod tests {
     use futures::StreamExt;
     use gpui::test::subscribe;
     use language::{
-        tree_sitter_rust, Diagnostic, FakeLspAdapter, LanguageConfig, LanguageServerConfig,
-        OffsetRangeExt, Point, ToPoint,
+        tree_sitter_rust, Diagnostic, FakeLspAdapter, LanguageConfig, OffsetRangeExt, Point,
+        ToPoint,
     };
     use lsp::Url;
     use serde_json::json;
@@ -4906,20 +4907,20 @@ mod tests {
     async fn test_disk_based_diagnostics_progress(cx: &mut gpui::TestAppContext) {
         cx.foreground().forbid_parking();
 
-        let progress_token = "the-progress-token".to_string();
+        let progress_token = "the-progress-token";
         let mut language = Language::new(
             LanguageConfig {
                 name: "Rust".into(),
                 path_suffixes: vec!["rs".to_string()],
-                language_server: LanguageServerConfig {
-                    disk_based_diagnostics_progress_token: Some(progress_token.clone()),
-                    ..Default::default()
-                },
                 ..Default::default()
             },
             Some(tree_sitter_rust::language()),
         );
-        let mut fake_servers = language.set_fake_lsp_adapter(Default::default());
+        let mut fake_servers = language.set_fake_lsp_adapter(FakeLspAdapter {
+            disk_based_diagnostics_progress_token: Some(progress_token),
+            disk_based_diagnostics_sources: &["disk"],
+            ..Default::default()
+        });
 
         let fs = FakeFs::new(cx.background());
         fs.insert_tree(
@@ -4956,15 +4957,15 @@ mod tests {
         let mut events = subscribe(&project, cx);
 
         let mut fake_server = fake_servers.next().await.unwrap();
-        fake_server.start_progress(&progress_token).await;
+        fake_server.start_progress(progress_token).await;
         assert_eq!(
             events.next().await.unwrap(),
             Event::DiskBasedDiagnosticsStarted
         );
 
-        fake_server.start_progress(&progress_token).await;
-        fake_server.end_progress(&progress_token).await;
-        fake_server.start_progress(&progress_token).await;
+        fake_server.start_progress(progress_token).await;
+        fake_server.end_progress(progress_token).await;
+        fake_server.start_progress(progress_token).await;
 
         fake_server.notify::<lsp::notification::PublishDiagnostics>(
             lsp::PublishDiagnosticsParams {
@@ -4983,8 +4984,8 @@ mod tests {
             Event::DiagnosticsUpdated((worktree_id, Path::new("a.rs")).into())
         );
 
-        fake_server.end_progress(&progress_token).await;
-        fake_server.end_progress(&progress_token).await;
+        fake_server.end_progress(progress_token).await;
+        fake_server.end_progress(progress_token).await;
         assert_eq!(
             events.next().await.unwrap(),
             Event::DiskBasedDiagnosticsUpdated
@@ -5024,20 +5025,18 @@ mod tests {
     async fn test_transforming_diagnostics(cx: &mut gpui::TestAppContext) {
         cx.foreground().forbid_parking();
 
-        // let (mut lsp_config, mut fake_servers) = LanguageServerConfig::fake();
         let mut language = Language::new(
             LanguageConfig {
                 name: "Rust".into(),
                 path_suffixes: vec!["rs".to_string()],
-                language_server: LanguageServerConfig {
-                    disk_based_diagnostic_sources: ["disk".to_string()].into_iter().collect(),
-                    ..Default::default()
-                },
                 ..Default::default()
             },
             Some(tree_sitter_rust::language()),
         );
-        let mut fake_servers = language.set_fake_lsp_adapter(Default::default());
+        let mut fake_servers = language.set_fake_lsp_adapter(FakeLspAdapter {
+            disk_based_diagnostics_sources: &["disk"],
+            ..Default::default()
+        });
 
         let text = "
             fn a() { A }
@@ -6551,9 +6550,7 @@ mod tests {
         };
 
         project
-            .update(cx, |p, cx| {
-                p.update_diagnostics(message, &Default::default(), cx)
-            })
+            .update(cx, |p, cx| p.update_diagnostics(message, &[], cx))
             .unwrap();
         let buffer = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 

crates/server/src/rpc.rs 🔗

@@ -5001,6 +5001,7 @@ mod tests {
                     });
                 }
             })),
+            ..Default::default()
         });
         host_language_registry.add(Arc::new(language));
 

crates/zed/src/languages/rust.rs 🔗

@@ -112,6 +112,14 @@ impl LspAdapter for RustLspAdapter {
         .boxed()
     }
 
+    fn disk_based_diagnostic_sources(&self) -> &'static [&'static str] {
+        &["rustc"]
+    }
+
+    fn disk_based_diagnostics_progress_token(&self) -> Option<&'static str> {
+        Some("rustAnalyzer/cargo check")
+    }
+
     fn process_diagnostics(&self, params: &mut lsp::PublishDiagnosticsParams) {
         lazy_static! {
             static ref REGEX: Regex = Regex::new("(?m)`([^`]+)\n`$").unwrap();

crates/zed/src/languages/rust/config.toml 🔗

@@ -10,7 +10,3 @@ brackets = [
     { start = "\"", end = "\"", close = true, newline = false },
     { start = "/*", end = " */", close = true, newline = false },
 ]
-
-[language_server]
-disk_based_diagnostic_sources = ["rustc"]
-disk_based_diagnostics_progress_token = "rustAnalyzer/cargo check"