vue_language_server_ext.rs

  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}