vue 3 comms initial idea working

Smit Barmase created

Change summary

crates/language/src/language.rs                         |  10 
crates/lsp/src/lsp.rs                                   |   6 
crates/project/src/lsp_store/vue_language_server_ext.rs | 132 +++-------
3 files changed, 57 insertions(+), 91 deletions(-)

Detailed changes

crates/language/src/language.rs 🔗

@@ -283,10 +283,16 @@ impl CachedLspAdapter {
     }
 
     pub fn language_id(&self, language_name: &LanguageName) -> String {
-        self.language_ids
+        let candidate = self
+            .language_ids
             .get(language_name)
             .cloned()
-            .unwrap_or_else(|| language_name.lsp_id())
+            .unwrap_or_else(|| language_name.lsp_id());
+        if candidate == "vue.js" {
+            "vue".into()
+        } else {
+            candidate
+        }
     }
 }
 

crates/lsp/src/lsp.rs 🔗

@@ -355,6 +355,7 @@ impl LanguageServer {
         let stdin = server.stdin.take().unwrap();
         let stdout = server.stdout.take().unwrap();
         let stderr = server.stderr.take().unwrap();
+        let name_for_logging = server_name.clone();
         let server = Self::new_internal(
             server_id,
             server_name,
@@ -370,7 +371,8 @@ impl LanguageServer {
             cx,
             move |notification| {
                 log::info!(
-                    "Language server with id {} sent unhandled notification {}:\n{}",
+                    "Language server `{}` with id {} sent unhandled notification {}:\n{}",
+                    name_for_logging.0,
                     server_id,
                     notification.method,
                     serde_json::to_string_pretty(&notification.params).unwrap(),
@@ -868,7 +870,7 @@ impl LanguageServer {
                     ..WindowClientCapabilities::default()
                 }),
             },
-            trace: None,
+            trace: Some(TraceValue::Verbose),
             workspace_folders: Some(workspace_folders),
             client_info: release_channel::ReleaseChannel::try_global(cx).map(|release_channel| {
                 ClientInfo {

crates/project/src/lsp_store/vue_language_server_ext.rs 🔗

@@ -1,38 +1,22 @@
 use anyhow::Context as _;
-use gpui::WeakEntity;
+use gpui::{AppContext, WeakEntity};
 use lsp::{LanguageServer, LanguageServerName};
-use serde::{Deserialize, Serialize};
+use serde_json::json;
 
 use crate::LspStore;
 
-struct TypescriptServerRequest;
+struct VueServerRequest;
 struct TypescriptServerResponse;
 
-#[derive(Serialize, Deserialize)]
-struct ServerRequestParams {
-    command: String,
-    arguments: ServerRequestArguments,
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(untagged)]
-enum ServerRequestArguments {
-    Data(String, serde_json::Value, Option<serde_json::Value>),
-}
-
-impl lsp::request::Request for TypescriptServerRequest {
-    type Params = ServerRequestParams;
-
-    type Result = serde_json::Value;
+impl lsp::notification::Notification for VueServerRequest {
+    type Params = [(u64, String, serde_json::Value); 1];
 
     const METHOD: &'static str = "tsserver/request";
 }
 
-impl lsp::request::Request for TypescriptServerResponse {
+impl lsp::notification::Notification for TypescriptServerResponse {
     type Params = serde_json::Value;
 
-    type Result = serde_json::Value;
-
     const METHOD: &'static str = "tsserver/response";
 }
 
@@ -40,83 +24,57 @@ const VUE_SERVER_NAME: LanguageServerName = LanguageServerName::new_static("vue-
 const VTSLS: LanguageServerName = LanguageServerName::new_static("vtsls");
 const TS_LS: LanguageServerName = LanguageServerName::new_static("typescript-language-server");
 
-// todo:
-//
-// 1. figure out req/res cycle
-//
-// What's the request and response name I should handle/send to vue language server?
-// The request and response names are not configurable:
-//     Request(receive from vue lsp): tsserver/request
-//     Response(send to vue lsp): tsserver/response
-//
-// 2. why hvoer/diagnsotic not working currently in vue
-// 3. when do we get tserver/reqest from vue lsp???
-//
-//
 pub fn register_requests(lsp_store: WeakEntity<LspStore>, language_server: &LanguageServer) {
     let language_server_name = language_server.name();
     if language_server_name == VUE_SERVER_NAME {
         let vue_server_id = language_server.server_id();
         language_server
-            .on_request::<TypescriptServerRequest, _, _>({
+            .on_notification::<VueServerRequest, _>({
                 let this = lsp_store.clone();
                 move |params, cx| {
                     let this = this.clone();
-                    let cx = cx.clone();
-                    async move {
-                        let language_server = this
-                            .read_with(&cx, |this, _| {
-                                let language_server_id = this
-                                    .as_local()
-                                    .and_then(|local| {
-                                        local.language_server_ids.iter().find_map(|(seed, v)| {
-                                            [VTSLS, TS_LS].contains(&seed.name).then_some(v.id)
-                                        })
+                    let Ok(target_server) = this
+                        .read_with(cx, |this, _| {
+                            let language_server_id = this
+                                .as_local()
+                                .and_then(|local| {
+                                    local.language_server_ids.iter().find_map(|(seed, v)| {
+                                        [VTSLS, TS_LS].contains(&seed.name).then_some(v.id)
                                     })
-                                    .context("Could not find language server")?;
+                                })
+                                .context("Could not find language server")?;
 
-                                this.language_server_for_id(language_server_id)
-                                    .context("language server not found")
-                            })
-                            .flatten()?;
-                        language_server
-                            .request::<TypescriptServerRequest>(params)
-                            .await
-                            .into_response()
-                            .map(|e| dbg!(e))
-                    }
-                }
-            })
-            .detach();
-    } else if language_server_name == VTSLS || language_server_name == TS_LS {
-        language_server
-            .on_request::<TypescriptServerResponse, _, _>({
-                let this = lsp_store.clone();
-                move |params, cx| {
-                    let this = this.clone();
+                            this.language_server_for_id(language_server_id)
+                                .context("language server not found")
+                        })
+                        .flatten()
+                    else {
+                        return;
+                    };
+                    let Some(vue_server) = this
+                        .read_with(cx, |this, _| this.language_server_for_id(vue_server_id))
+                        .ok()
+                        .flatten()
+                    else {
+                        return;
+                    };
                     let cx = cx.clone();
-                    async move {
-                        let language_server = this
-                            .read_with(&cx, |this, _| {
-                                let language_server_id = this
-                                    .as_local()
-                                    .and_then(|local| {
-                                        local.language_server_ids.iter().find_map(|(seed, v)| {
-                                            // todo: improve this
-                                            [VUE_SERVER_NAME].contains(&seed.name).then_some(v.id)
-                                        })
-                                    })
-                                    .context("Could not find language server")?;
-
-                                this.language_server_for_id(language_server_id)
-                                    .context("language server not found")
+                    cx.background_spawn(async move {
+                        let (request_id, command, arguments) = params[0].clone();
+                        let tsserver_response = target_server
+                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
+                                command: "typescript.tsserverRequest".to_owned(),
+                                arguments: vec![serde_json::Value::String(command), arguments],
+                                ..Default::default()
                             })
-                            .flatten()?;
-                        language_server
-                            .request::<TypescriptServerResponse>(params)
-                            .await
-                            .into_response()
-                    }
+                            .await;
+                        if let util::ConnectionResult::Result(Ok(result)) = tsserver_response {
+                            _ = vue_server.notify::<TypescriptServerResponse>(
+                                &json!({ "id": request_id, "response": result }),
+                            );
+                        }
+                    })
+                    .detach();
                 }
             })
             .detach();