intelephense.rs

 1use std::fs;
 2
 3use zed_extension_api::{self as zed, LanguageServerId, Result};
 4
 5const SERVER_PATH: &str = "node_modules/intelephense/lib/intelephense.js";
 6const PACKAGE_NAME: &str = "intelephense";
 7
 8pub struct Intelephense {
 9    did_find_server: bool,
10}
11
12impl Intelephense {
13    pub const LANGUAGE_SERVER_ID: &'static str = "intelephense";
14
15    pub fn new() -> Self {
16        Self {
17            did_find_server: false,
18        }
19    }
20
21    fn server_exists(&self) -> bool {
22        fs::metadata(SERVER_PATH).map_or(false, |stat| stat.is_file())
23    }
24
25    pub fn server_script_path(&mut self, language_server_id: &LanguageServerId) -> Result<String> {
26        let server_exists = self.server_exists();
27        if self.did_find_server && server_exists {
28            return Ok(SERVER_PATH.to_string());
29        }
30
31        zed::set_language_server_installation_status(
32            &language_server_id,
33            &zed::LanguageServerInstallationStatus::CheckingForUpdate,
34        );
35        let version = zed::npm_package_latest_version(PACKAGE_NAME)?;
36
37        if !server_exists
38            || zed::npm_package_installed_version(PACKAGE_NAME)?.as_ref() != Some(&version)
39        {
40            zed::set_language_server_installation_status(
41                &language_server_id,
42                &zed::LanguageServerInstallationStatus::Downloading,
43            );
44            let result = zed::npm_install_package(PACKAGE_NAME, &version);
45            match result {
46                Ok(()) => {
47                    if !self.server_exists() {
48                        Err(format!(
49                            "installed package '{PACKAGE_NAME}' did not contain expected path '{SERVER_PATH}'",
50                        ))?;
51                    }
52                }
53                Err(error) => {
54                    if !self.server_exists() {
55                        Err(error)?;
56                    }
57                }
58            }
59        }
60
61        self.did_find_server = true;
62        Ok(SERVER_PATH.to_string())
63    }
64}