@@ -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
+ }
}
}
@@ -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 {
@@ -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();