Initial unstyled language server short name in completions

Julia and Kirill Bulatov created

Co-Authored-By: Kirill Bulatov <kirill@zed.dev>

Change summary

crates/editor/src/editor.rs            | 61 ++++++++++++++++++++++-----
crates/language/src/language.rs        |  9 ++++
crates/zed/src/languages/c.rs          |  4 +
crates/zed/src/languages/css.rs        |  4 +
crates/zed/src/languages/elixir.rs     |  4 +
crates/zed/src/languages/go.rs         |  4 +
crates/zed/src/languages/html.rs       |  4 +
crates/zed/src/languages/json.rs       |  4 +
crates/zed/src/languages/lua.rs        |  4 +
crates/zed/src/languages/php.rs        |  4 +
crates/zed/src/languages/python.rs     |  4 +
crates/zed/src/languages/ruby.rs       |  4 +
crates/zed/src/languages/rust.rs       |  4 +
crates/zed/src/languages/svelte.rs     |  4 +
crates/zed/src/languages/tailwind.rs   |  4 +
crates/zed/src/languages/typescript.rs |  8 +++
crates/zed/src/languages/yaml.rs       |  4 +
17 files changed, 121 insertions(+), 13 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -810,6 +810,7 @@ struct CompletionsMenu {
     id: CompletionId,
     initial_position: Anchor,
     buffer: ModelHandle<Buffer>,
+    project: Option<ModelHandle<Project>>,
     completions: Arc<[Completion]>,
     match_candidates: Vec<StringMatchCandidate>,
     matches: Arc<[StringMatch]>,
@@ -853,6 +854,26 @@ impl CompletionsMenu {
     fn render(&self, style: EditorStyle, cx: &mut ViewContext<Editor>) -> AnyElement<Editor> {
         enum CompletionTag {}
 
+        let language_servers = self.project.as_ref().map(|project| {
+            project
+                .read(cx)
+                .language_servers_for_buffer(self.buffer.read(cx), cx)
+                .map(|(adapter, server)| (server.server_id(), format!("{}: ", adapter.short_name)))
+                .collect::<Vec<_>>()
+        });
+        let get_server_name = move |lookup_server_id: lsp::LanguageServerId| -> Option<String> {
+            language_servers
+                .iter()
+                .flatten()
+                .find_map(|(server_id, server_name)| {
+                    if *server_id == lookup_server_id {
+                        Some(server_name.clone())
+                    } else {
+                        None
+                    }
+                })
+        };
+
         let completions = self.completions.clone();
         let matches = self.matches.clone();
         let selected_item = self.selected_item;
@@ -879,19 +900,31 @@ impl CompletionsMenu {
                                     style.autocomplete.item
                                 };
 
-                                Text::new(completion.label.text.clone(), style.text.clone())
-                                    .with_soft_wrap(false)
-                                    .with_highlights(combine_syntax_and_fuzzy_match_highlights(
-                                        &completion.label.text,
-                                        style.text.color.into(),
-                                        styled_runs_for_code_label(
-                                            &completion.label,
-                                            &style.syntax,
-                                        ),
-                                        &mat.positions,
-                                    ))
-                                    .contained()
-                                    .with_style(item_style)
+                                let completion_label =
+                                    Text::new(completion.label.text.clone(), style.text.clone())
+                                        .with_soft_wrap(false)
+                                        .with_highlights(
+                                            combine_syntax_and_fuzzy_match_highlights(
+                                                &completion.label.text,
+                                                style.text.color.into(),
+                                                styled_runs_for_code_label(
+                                                    &completion.label,
+                                                    &style.syntax,
+                                                ),
+                                                &mat.positions,
+                                            ),
+                                        );
+
+                                if let Some(server_name) = get_server_name(completion.server_id) {
+                                    Flex::row()
+                                        .with_child(Text::new(server_name, style.text.clone()))
+                                        .with_child(completion_label)
+                                        .into_any()
+                                } else {
+                                    completion_label.into_any()
+                                }
+                                .contained()
+                                .with_style(item_style)
                             },
                         )
                         .with_cursor_style(CursorStyle::PointingHand)
@@ -2850,6 +2883,7 @@ impl Editor {
         });
 
         let id = post_inc(&mut self.next_completion_id);
+        let project = self.project.clone();
         let task = cx.spawn(|this, mut cx| {
             async move {
                 let menu = if let Some(completions) = completions.await.log_err() {
@@ -2868,6 +2902,7 @@ impl Editor {
                             })
                             .collect(),
                         buffer,
+                        project,
                         completions: completions.into(),
                         matches: Vec::new().into(),
                         selected_item: 0,

crates/language/src/language.rs 🔗

@@ -90,6 +90,7 @@ pub struct LanguageServerName(pub Arc<str>);
 /// once at startup, and caches the results.
 pub struct CachedLspAdapter {
     pub name: LanguageServerName,
+    pub short_name: &'static str,
     pub initialization_options: Option<Value>,
     pub disk_based_diagnostic_sources: Vec<String>,
     pub disk_based_diagnostics_progress_token: Option<String>,
@@ -100,6 +101,7 @@ pub struct CachedLspAdapter {
 impl CachedLspAdapter {
     pub async fn new(adapter: Arc<dyn LspAdapter>) -> Arc<Self> {
         let name = adapter.name().await;
+        let short_name = adapter.short_name();
         let initialization_options = adapter.initialization_options().await;
         let disk_based_diagnostic_sources = adapter.disk_based_diagnostic_sources().await;
         let disk_based_diagnostics_progress_token =
@@ -108,6 +110,7 @@ impl CachedLspAdapter {
 
         Arc::new(CachedLspAdapter {
             name,
+            short_name,
             initialization_options,
             disk_based_diagnostic_sources,
             disk_based_diagnostics_progress_token,
@@ -216,6 +219,8 @@ pub trait LspAdapterDelegate: Send + Sync {
 pub trait LspAdapter: 'static + Send + Sync {
     async fn name(&self) -> LanguageServerName;
 
+    fn short_name(&self) -> &'static str;
+
     async fn fetch_latest_server_version(
         &self,
         delegate: &dyn LspAdapterDelegate,
@@ -1696,6 +1701,10 @@ impl LspAdapter for Arc<FakeLspAdapter> {
         LanguageServerName(self.name.into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "FakeLspAdapter"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         _: &dyn LspAdapterDelegate,

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

@@ -19,6 +19,10 @@ impl super::LspAdapter for CLspAdapter {
         LanguageServerName("clangd".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "clangd"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         delegate: &dyn LspAdapterDelegate,

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

@@ -37,6 +37,10 @@ impl LspAdapter for CssLspAdapter {
         LanguageServerName("vscode-css-language-server".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "css"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         _: &dyn LspAdapterDelegate,

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

@@ -27,6 +27,10 @@ impl LspAdapter for ElixirLspAdapter {
         LanguageServerName("elixir-ls".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "elixir-ls"
+    }
+
     fn will_start_server(
         &self,
         delegate: &Arc<dyn LspAdapterDelegate>,

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

@@ -37,6 +37,10 @@ impl super::LspAdapter for GoLspAdapter {
         LanguageServerName("gopls".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "gopls"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         delegate: &dyn LspAdapterDelegate,

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

@@ -37,6 +37,10 @@ impl LspAdapter for HtmlLspAdapter {
         LanguageServerName("vscode-html-language-server".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "html"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         _: &dyn LspAdapterDelegate,

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

@@ -43,6 +43,10 @@ impl LspAdapter for JsonLspAdapter {
         LanguageServerName("json-language-server".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "json"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         _: &dyn LspAdapterDelegate,

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

@@ -29,6 +29,10 @@ impl super::LspAdapter for LuaLspAdapter {
         LanguageServerName("lua-language-server".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "lua"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         delegate: &dyn LspAdapterDelegate,

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

@@ -41,6 +41,10 @@ impl LspAdapter for IntelephenseLspAdapter {
         LanguageServerName("intelephense".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "php"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         _delegate: &dyn LspAdapterDelegate,

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

@@ -35,6 +35,10 @@ impl LspAdapter for PythonLspAdapter {
         LanguageServerName("pyright".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "pyright"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         _: &dyn LspAdapterDelegate,

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

@@ -12,6 +12,10 @@ impl LspAdapter for RubyLanguageServer {
         LanguageServerName("solargraph".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "solargraph"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         _: &dyn LspAdapterDelegate,

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

@@ -22,6 +22,10 @@ impl LspAdapter for RustLspAdapter {
         LanguageServerName("rust-analyzer".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "rust"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         delegate: &dyn LspAdapterDelegate,

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

@@ -36,6 +36,10 @@ impl LspAdapter for SvelteLspAdapter {
         LanguageServerName("svelte-language-server".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "svelte"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         _: &dyn LspAdapterDelegate,

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

@@ -41,6 +41,10 @@ impl LspAdapter for TailwindLspAdapter {
         LanguageServerName("tailwindcss-language-server".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "tailwind"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         _: &dyn LspAdapterDelegate,

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

@@ -56,6 +56,10 @@ impl LspAdapter for TypeScriptLspAdapter {
         LanguageServerName("typescript-language-server".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "tsserver"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         _: &dyn LspAdapterDelegate,
@@ -218,6 +222,10 @@ impl LspAdapter for EsLintLspAdapter {
         LanguageServerName("eslint".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "eslint"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         delegate: &dyn LspAdapterDelegate,

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

@@ -40,6 +40,10 @@ impl LspAdapter for YamlLspAdapter {
         LanguageServerName("yaml-language-server".into())
     }
 
+    fn short_name(&self) -> &'static str {
+        "yaml"
+    }
+
     async fn fetch_latest_server_version(
         &self,
         _: &dyn LspAdapterDelegate,