1use anyhow::Context as _;
2use gpui::WeakEntity;
3use lsp::{LanguageServer, LanguageServerName};
4use serde::{Deserialize, Serialize};
5
6use crate::LspStore;
7
8struct TypescriptServerRequest;
9struct TypescriptServerResponse;
10
11#[derive(Serialize, Deserialize)]
12struct ServerRequestParams {
13 command: String,
14 arguments: ServerRequestArguments,
15}
16
17#[derive(Serialize, Deserialize)]
18#[serde(untagged)]
19enum ServerRequestArguments {
20 Data(String, serde_json::Value, Option<serde_json::Value>),
21}
22
23impl lsp::request::Request for TypescriptServerRequest {
24 type Params = ServerRequestParams;
25
26 type Result = serde_json::Value;
27
28 const METHOD: &'static str = "tsserver/request";
29}
30
31impl lsp::request::Request for TypescriptServerResponse {
32 type Params = serde_json::Value;
33
34 type Result = serde_json::Value;
35
36 const METHOD: &'static str = "tsserver/response";
37}
38
39const VUE_SERVER_NAME: LanguageServerName = LanguageServerName::new_static("vue-language-server");
40const VTSLS: LanguageServerName = LanguageServerName::new_static("vtsls");
41const TS_LS: LanguageServerName = LanguageServerName::new_static("typescript-language-server");
42
43// todo:
44//
45// 1. figure out req/res cycle
46//
47// What's the request and response name I should handle/send to vue language server?
48// The request and response names are not configurable:
49// Request(receive from vue lsp): tsserver/request
50// Response(send to vue lsp): tsserver/response
51//
52// 2. why hvoer/diagnsotic not working currently in vue
53// 3. when do we get tserver/reqest from vue lsp???
54//
55//
56pub fn register_requests(lsp_store: WeakEntity<LspStore>, language_server: &LanguageServer) {
57 let language_server_name = language_server.name();
58 if language_server_name == VUE_SERVER_NAME {
59 let vue_server_id = language_server.server_id();
60 language_server
61 .on_request::<TypescriptServerRequest, _, _>({
62 let this = lsp_store.clone();
63 move |params, cx| {
64 let this = this.clone();
65 let cx = cx.clone();
66 async move {
67 let language_server = this
68 .read_with(&cx, |this, _| {
69 let language_server_id = this
70 .as_local()
71 .and_then(|local| {
72 local.language_server_ids.iter().find_map(|(seed, v)| {
73 [VTSLS, TS_LS].contains(&seed.name).then_some(v.id)
74 })
75 })
76 .context("Could not find language server")?;
77
78 this.language_server_for_id(language_server_id)
79 .context("language server not found")
80 })
81 .flatten()?;
82 language_server
83 .request::<TypescriptServerRequest>(params)
84 .await
85 .into_response()
86 .map(|e| dbg!(e))
87 }
88 }
89 })
90 .detach();
91 } else if language_server_name == VTSLS || language_server_name == TS_LS {
92 language_server
93 .on_request::<TypescriptServerResponse, _, _>({
94 let this = lsp_store.clone();
95 move |params, cx| {
96 let this = this.clone();
97 let cx = cx.clone();
98 async move {
99 let language_server = this
100 .read_with(&cx, |this, _| {
101 let language_server_id = this
102 .as_local()
103 .and_then(|local| {
104 local.language_server_ids.iter().find_map(|(seed, v)| {
105 // todo: improve this
106 [VUE_SERVER_NAME].contains(&seed.name).then_some(v.id)
107 })
108 })
109 .context("Could not find language server")?;
110
111 this.language_server_for_id(language_server_id)
112 .context("language server not found")
113 })
114 .flatten()?;
115 language_server
116 .request::<TypescriptServerResponse>(params)
117 .await
118 .into_response()
119 }
120 }
121 })
122 .detach();
123 }
124}