Merge pull request #1334 from zed-industries/plugin-id-for-language

Max Brunsfeld created

Fix association of 'json' lsp language id with JSON language

Change summary

crates/language/src/language.rs             | 10 +++++-----
crates/project/src/project.rs               |  7 ++++---
crates/zed/src/languages/language_plugin.rs | 15 +++++++++++++++
plugins/json_language/src/lib.rs            |  8 ++------
4 files changed, 26 insertions(+), 14 deletions(-)

Detailed changes

crates/language/src/language.rs 🔗

@@ -74,7 +74,7 @@ pub struct CachedLspAdapter {
     pub initialization_options: Option<Value>,
     pub disk_based_diagnostic_sources: Vec<String>,
     pub disk_based_diagnostics_progress_token: Option<String>,
-    pub id_for_language: Option<String>,
+    pub language_ids: HashMap<String, String>,
     pub adapter: Box<dyn LspAdapter>,
 }
 
@@ -87,7 +87,7 @@ impl CachedLspAdapter {
         let disk_based_diagnostic_sources = adapter.disk_based_diagnostic_sources().await;
         let disk_based_diagnostics_progress_token =
             adapter.disk_based_diagnostics_progress_token().await;
-        let id_for_language = adapter.id_for_language(name.0.as_ref()).await;
+        let language_ids = adapter.language_ids().await;
 
         Arc::new(CachedLspAdapter {
             name,
@@ -95,7 +95,7 @@ impl CachedLspAdapter {
             initialization_options,
             disk_based_diagnostic_sources,
             disk_based_diagnostics_progress_token,
-            id_for_language,
+            language_ids,
             adapter,
         })
     }
@@ -199,8 +199,8 @@ pub trait LspAdapter: 'static + Send + Sync {
         None
     }
 
-    async fn id_for_language(&self, _name: &str) -> Option<String> {
-        None
+    async fn language_ids(&self) -> HashMap<String, String> {
+        Default::default()
     }
 }
 

crates/project/src/project.rs 🔗

@@ -1821,7 +1821,7 @@ impl Project {
                 if let Some(language) = buffer.language() {
                     let worktree_id = file.worktree_id(cx);
                     if let Some(adapter) = language.lsp_adapter() {
-                        language_id = adapter.id_for_language.clone();
+                        language_id = adapter.language_ids.get(language.name().as_ref()).cloned();
                         language_server = self
                             .language_server_ids
                             .get(&(worktree_id, adapter.name.clone()))
@@ -2320,8 +2320,9 @@ impl Project {
                                                 text_document: lsp::TextDocumentItem::new(
                                                     uri,
                                                     adapter
-                                                        .id_for_language
-                                                        .clone()
+                                                        .language_ids
+                                                        .get(language.name().as_ref())
+                                                        .cloned()
                                                         .unwrap_or_default(),
                                                     *version,
                                                     initial_snapshot.text(),

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

@@ -1,6 +1,7 @@
 use anyhow::{anyhow, Result};
 use async_trait::async_trait;
 use client::http::HttpClient;
+use collections::HashMap;
 use futures::lock::Mutex;
 use gpui::executor::Background;
 use language::{LanguageServerName, LspAdapter};
@@ -35,6 +36,7 @@ pub struct PluginLspAdapter {
     fetch_server_binary: WasiFn<(PathBuf, String), Result<PathBuf, String>>,
     cached_server_binary: WasiFn<PathBuf, Option<PathBuf>>,
     initialization_options: WasiFn<(), String>,
+    language_ids: WasiFn<(), Vec<(String, String)>>,
     executor: Arc<Background>,
     runtime: Arc<Mutex<Plugin>>,
 }
@@ -48,6 +50,7 @@ impl PluginLspAdapter {
             fetch_server_binary: plugin.function("fetch_server_binary")?,
             cached_server_binary: plugin.function("cached_server_binary")?,
             initialization_options: plugin.function("initialization_options")?,
+            language_ids: plugin.function("language_ids")?,
             executor,
             runtime: Arc::new(Mutex::new(plugin)),
         })
@@ -142,4 +145,16 @@ impl LspAdapter for PluginLspAdapter {
 
         serde_json::from_str(&string).ok()
     }
+
+    async fn language_ids(&self) -> HashMap<String, String> {
+        self.runtime
+            .lock()
+            .await
+            .call(&self.language_ids, ())
+            .await
+            .log_err()
+            .unwrap_or_default()
+            .into_iter()
+            .collect()
+    }
 }

plugins/json_language/src/lib.rs 🔗

@@ -94,10 +94,6 @@ pub fn initialization_options() -> Option<String> {
 }
 
 #[export]
-pub fn id_for_language(name: String) -> Option<String> {
-    if name == "JSON" {
-        Some("jsonc".into())
-    } else {
-        None
-    }
+pub fn language_ids() -> Vec<(String, String)> {
+    vec![("JSON".into(), "jsonc".into())]
 }