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}