extension_lsp_adapter.rs

 1use crate::wasm_host::{wit::LanguageServerConfig, WasmExtension, WasmHost};
 2use anyhow::{anyhow, Result};
 3use async_trait::async_trait;
 4use futures::{Future, FutureExt};
 5use gpui::AsyncAppContext;
 6use language::{Language, LanguageServerName, LspAdapter, LspAdapterDelegate};
 7use lsp::LanguageServerBinary;
 8use std::{
 9    any::Any,
10    path::{Path, PathBuf},
11    pin::Pin,
12    sync::Arc,
13};
14use wasmtime_wasi::preview2::WasiView as _;
15
16pub struct ExtensionLspAdapter {
17    pub(crate) extension: WasmExtension,
18    pub(crate) config: LanguageServerConfig,
19    pub(crate) host: Arc<WasmHost>,
20}
21
22#[async_trait(?Send)]
23impl LspAdapter for ExtensionLspAdapter {
24    fn name(&self) -> LanguageServerName {
25        LanguageServerName(self.config.name.clone().into())
26    }
27
28    fn get_language_server_command<'a>(
29        self: Arc<Self>,
30        _: Arc<Language>,
31        _: Arc<Path>,
32        delegate: Arc<dyn LspAdapterDelegate>,
33        _: futures::lock::MutexGuard<'a, Option<LanguageServerBinary>>,
34        _: &'a mut AsyncAppContext,
35    ) -> Pin<Box<dyn 'a + Future<Output = Result<LanguageServerBinary>>>> {
36        async move {
37            let command = self
38                .extension
39                .call({
40                    let this = self.clone();
41                    |extension, store| {
42                        async move {
43                            let resource = store.data_mut().table().push(delegate)?;
44                            let command = extension
45                                .call_language_server_command(store, &this.config, resource)
46                                .await?
47                                .map_err(|e| anyhow!("{}", e))?;
48                            anyhow::Ok(command)
49                        }
50                        .boxed()
51                    }
52                })
53                .await?;
54
55            let path = self
56                .host
57                .path_from_extension(&self.extension.manifest.id, command.command.as_ref());
58
59            Ok(LanguageServerBinary {
60                path,
61                arguments: command.args.into_iter().map(|arg| arg.into()).collect(),
62                env: Some(command.env.into_iter().collect()),
63            })
64        }
65        .boxed_local()
66    }
67
68    async fn fetch_latest_server_version(
69        &self,
70        _: &dyn LspAdapterDelegate,
71    ) -> Result<Box<dyn 'static + Send + Any>> {
72        unreachable!("get_language_server_command is overridden")
73    }
74
75    async fn fetch_server_binary(
76        &self,
77        _: Box<dyn 'static + Send + Any>,
78        _: PathBuf,
79        _: &dyn LspAdapterDelegate,
80    ) -> Result<LanguageServerBinary> {
81        unreachable!("get_language_server_command is overridden")
82    }
83
84    async fn cached_server_binary(
85        &self,
86        _: PathBuf,
87        _: &dyn LspAdapterDelegate,
88    ) -> Option<LanguageServerBinary> {
89        unreachable!("get_language_server_command is overridden")
90    }
91
92    async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
93        None
94    }
95}