Add prettier language servers to LSP logs panel

Kirill Bulatov created

Change summary

crates/prettier/src/prettier.rs | 68 +++++++++++++++++++---------------
crates/project/src/project.rs   | 27 +++++++++++--
2 files changed, 59 insertions(+), 36 deletions(-)

Detailed changes

crates/prettier/src/prettier.rs 🔗

@@ -4,7 +4,7 @@ use std::sync::Arc;
 
 use anyhow::Context;
 use fs::Fs;
-use gpui::{AsyncAppContext, ModelHandle, Task};
+use gpui::{AsyncAppContext, ModelHandle};
 use language::language_settings::language_settings;
 use language::{Buffer, BundledFormatter, Diff};
 use lsp::{LanguageServer, LanguageServerBinary, LanguageServerId};
@@ -147,40 +147,42 @@ impl Prettier {
         }
     }
 
-    pub fn start(
+    pub async fn start(
+        server_id: LanguageServerId,
         prettier_dir: PathBuf,
         node: Arc<dyn NodeRuntime>,
         cx: AsyncAppContext,
-    ) -> Task<anyhow::Result<Self>> {
-        cx.spawn(|cx| async move {
-            anyhow::ensure!(
-                prettier_dir.is_dir(),
-                "Prettier dir {prettier_dir:?} is not a directory"
-            );
-            let prettier_server = DEFAULT_PRETTIER_DIR.join(PRETTIER_SERVER_FILE);
-            anyhow::ensure!(
-                prettier_server.is_file(),
-                "no prettier server package found at {prettier_server:?}"
-            );
+    ) -> anyhow::Result<Self> {
+        let backgroud = cx.background();
+        anyhow::ensure!(
+            prettier_dir.is_dir(),
+            "Prettier dir {prettier_dir:?} is not a directory"
+        );
+        let prettier_server = DEFAULT_PRETTIER_DIR.join(PRETTIER_SERVER_FILE);
+        anyhow::ensure!(
+            prettier_server.is_file(),
+            "no prettier server package found at {prettier_server:?}"
+        );
 
-            let node_path = node.binary_path().await?;
-            let server = LanguageServer::new(
-                LanguageServerId(0),
-                LanguageServerBinary {
-                    path: node_path,
-                    arguments: vec![prettier_server.into(), prettier_dir.into()],
-                },
-                Path::new("/"),
-                None,
-                cx,
-            )
-            .context("prettier server creation")?;
-            let server = server
-                .initialize(None)
-                .await
-                .context("prettier server initialization")?;
-            Ok(Self { server })
-        })
+        let node_path = backgroud
+            .spawn(async move { node.binary_path().await })
+            .await?;
+        let server = LanguageServer::new(
+            server_id,
+            LanguageServerBinary {
+                path: node_path,
+                arguments: vec![prettier_server.into(), prettier_dir.into()],
+            },
+            Path::new("/"),
+            None,
+            cx,
+        )
+        .context("prettier server creation")?;
+        let server = backgroud
+            .spawn(server.initialize(None))
+            .await
+            .context("prettier server initialization")?;
+        Ok(Self { server })
     }
 
     pub async fn format(
@@ -228,6 +230,10 @@ impl Prettier {
     pub async fn clear_cache(&self) -> anyhow::Result<()> {
         todo!()
     }
+
+    pub fn server(&self) -> &Arc<LanguageServer> {
+        &self.server
+    }
 }
 
 async fn find_closest_prettier_dir(

crates/project/src/project.rs 🔗

@@ -8283,12 +8283,29 @@ impl Project {
                 return existing_prettier;
             }
 
-            let start_task = Prettier::start(prettier_dir.clone(), node, cx.clone());
+            let task_prettier_dir = prettier_dir.clone();
+            let weak_project = this.downgrade();
+            let new_server_id =
+                this.update(&mut cx, |this, _| this.languages.next_language_server_id());
             let new_prettier_task = cx
-                .background()
-                .spawn(async move {
-                    Ok(Arc::new(start_task.await.context("starting new prettier")?))
-                        .map_err(Arc::new)
+                .spawn(|mut cx| async move {
+                    let prettier =
+                        Prettier::start(new_server_id, task_prettier_dir, node, cx.clone())
+                            .await
+                            .context("prettier start")
+                            .map_err(Arc::new)?;
+                    if let Some(project) = weak_project.upgrade(&mut cx) {
+                        let prettier_server = Arc::clone(prettier.server());
+                        project.update(&mut cx, |project, cx| {
+                            project.supplementary_language_servers.insert(
+                                new_server_id,
+                                // TODO kb same name repeats for different prettiers, distinguish
+                                (LanguageServerName(Arc::from("prettier")), prettier_server),
+                            );
+                            cx.emit(Event::LanguageServerAdded(new_server_id));
+                        });
+                    }
+                    anyhow::Ok(Arc::new(prettier)).map_err(Arc::new)
                 })
                 .shared();
             this.update(&mut cx, |project, _| {