extension_lsp_adapter.rs

 1use crate::wasm_host::{wit::LanguageServerConfig, WasmExtension};
 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) work_dir: PathBuf,
20}
21
22#[async_trait]
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                            extension
45                                .call_language_server_command(store, &this.config, resource)
46                                .await
47                        }
48                        .boxed()
49                    }
50                })
51                .await?
52                .map_err(|e| anyhow!("{}", e))?;
53
54            Ok(LanguageServerBinary {
55                path: self.work_dir.join(&command.command),
56                arguments: command.args.into_iter().map(|arg| arg.into()).collect(),
57                env: Some(command.env.into_iter().collect()),
58            })
59        }
60        .boxed_local()
61    }
62
63    async fn fetch_latest_server_version(
64        &self,
65        _: &dyn LspAdapterDelegate,
66    ) -> Result<Box<dyn 'static + Send + Any>> {
67        unreachable!("get_language_server_command is overridden")
68    }
69
70    async fn fetch_server_binary(
71        &self,
72        _: Box<dyn 'static + Send + Any>,
73        _: PathBuf,
74        _: &dyn LspAdapterDelegate,
75    ) -> Result<LanguageServerBinary> {
76        unreachable!("get_language_server_command is overridden")
77    }
78
79    async fn cached_server_binary(
80        &self,
81        _: PathBuf,
82        _: &dyn LspAdapterDelegate,
83    ) -> Option<LanguageServerBinary> {
84        unreachable!("get_language_server_command is overridden")
85    }
86
87    async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
88        None
89    }
90}