From 6f9834058e3f86d1b62839706bcef5932a32cdfe Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Thu, 18 Sep 2025 18:22:33 +0530 Subject: [PATCH] vue 3 comms initial idea working --- crates/language/src/language.rs | 10 +- crates/lsp/src/lsp.rs | 6 +- .../src/lsp_store/vue_language_server_ext.rs | 132 ++++++------------ 3 files changed, 57 insertions(+), 91 deletions(-) diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 77e8ee0232819a830e48d1d12a778ef19026d7b6..3f67cc8d7649b4db8824ad9ebb21572868e19464 100644 --- a/crates/language/src/language.rs +++ b/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 + } } } diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index fda188be8bec8b8c8a48b888243290b31c10f149..9dc7686c8c92e10b469c793d4491c703abf29aa8 100644 --- a/crates/lsp/src/lsp.rs +++ b/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(¬ification.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 { diff --git a/crates/project/src/lsp_store/vue_language_server_ext.rs b/crates/project/src/lsp_store/vue_language_server_ext.rs index 3af65114ec70b9da334f5c4e56a007b805925cc0..54b2e8bb79ecb4a6edd0baf2c6ac520b883d0331 100644 --- a/crates/project/src/lsp_store/vue_language_server_ext.rs +++ b/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), -} - -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, 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::({ + .on_notification::({ 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::(params) - .await - .into_response() - .map(|e| dbg!(e)) - } - } - }) - .detach(); - } else if language_server_name == VTSLS || language_server_name == TS_LS { - language_server - .on_request::({ - 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::ExecuteCommandParams { + command: "typescript.tsserverRequest".to_owned(), + arguments: vec![serde_json::Value::String(command), arguments], + ..Default::default() }) - .flatten()?; - language_server - .request::(params) - .await - .into_response() - } + .await; + if let util::ConnectionResult::Result(Ok(result)) = tsserver_response { + _ = vue_server.notify::( + &json!({ "id": request_id, "response": result }), + ); + } + }) + .detach(); } }) .detach();