vue_language_server_ext.rs

 1use anyhow::Context as _;
 2use gpui::{AppContext, WeakEntity};
 3use lsp::{LanguageServer, LanguageServerName};
 4use serde_json::json;
 5
 6use crate::LspStore;
 7
 8struct VueServerRequest;
 9struct TypescriptServerResponse;
10
11impl lsp::notification::Notification for VueServerRequest {
12    type Params = [(u64, String, serde_json::Value); 1];
13
14    const METHOD: &'static str = "tsserver/request";
15}
16
17impl lsp::notification::Notification for TypescriptServerResponse {
18    type Params = serde_json::Value;
19
20    const METHOD: &'static str = "tsserver/response";
21}
22
23const VUE_SERVER_NAME: LanguageServerName = LanguageServerName::new_static("vue-language-server");
24const VTSLS: LanguageServerName = LanguageServerName::new_static("vtsls");
25const TS_LS: LanguageServerName = LanguageServerName::new_static("typescript-language-server");
26
27pub fn register_requests(lsp_store: WeakEntity<LspStore>, language_server: &LanguageServer) {
28    let language_server_name = language_server.name();
29    if language_server_name == VUE_SERVER_NAME {
30        let vue_server_id = language_server.server_id();
31        language_server
32            .on_notification::<VueServerRequest, _>({
33                let this = lsp_store.clone();
34                move |params, cx| {
35                    let this = this.clone();
36                    let Ok(target_server) = this
37                        .read_with(cx, |this, _| {
38                            let language_server_id = this
39                                .as_local()
40                                .and_then(|local| {
41                                    local.language_server_ids.iter().find_map(|(seed, v)| {
42                                        [VTSLS, TS_LS].contains(&seed.name).then_some(v.id)
43                                    })
44                                })
45                                .context("Could not find language server")?;
46
47                            this.language_server_for_id(language_server_id)
48                                .context("language server not found")
49                        })
50                        .flatten()
51                    else {
52                        return;
53                    };
54                    let Some(vue_server) = this
55                        .read_with(cx, |this, _| this.language_server_for_id(vue_server_id))
56                        .ok()
57                        .flatten()
58                    else {
59                        return;
60                    };
61                    let cx = cx.clone();
62                    cx.background_spawn(async move {
63                        let (request_id, command, arguments) = params[0].clone();
64                        let tsserver_response = target_server
65                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
66                                command: "typescript.tsserverRequest".to_owned(),
67                                arguments: vec![serde_json::Value::String(command), arguments],
68                                ..Default::default()
69                            })
70                            .await;
71                        if let util::ConnectionResult::Result(Ok(result)) = tsserver_response {
72                            _ = vue_server.notify::<TypescriptServerResponse>(
73                                &json!({ "id": request_id, "response": result }),
74                            );
75                        }
76                    })
77                    .detach();
78                }
79            })
80            .detach();
81    }
82}