Skip to content

Commit 322204f

Browse files
committed
Install lsp server from user configuration.
1 parent b3ce82b commit 322204f

1 file changed

Lines changed: 52 additions & 7 deletions

File tree

src/rescript.rs

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
use std::{borrow::Cow, env, fs};
2+
use zed_extension_api::serde_json::Value;
3+
use zed_extension_api::settings::LspSettings;
24
use zed_extension_api::{self as zed, Result};
35

46
const SERVER_PATH: &str = "node_modules/@rescript/language-server/out/cli.js";
@@ -8,14 +10,49 @@ struct ReScriptExtension {
810
did_find_server: bool,
911
}
1012

13+
#[derive(Debug, Default)]
14+
struct Settings {
15+
version: Option<String>,
16+
}
17+
18+
fn parse_settings(settings_value: Value) -> Settings {
19+
if let Some(obj) = settings_value.as_object() {
20+
return Settings {
21+
version: obj
22+
.get("version")
23+
.and_then(|v| v.as_str())
24+
.map(|s| s.to_string()),
25+
};
26+
}
27+
28+
Settings::default()
29+
}
30+
1131
impl ReScriptExtension {
1232
fn server_exists(&self) -> bool {
13-
fs::metadata(SERVER_PATH).map_or(false, |stat| stat.is_file())
33+
fs::metadata(SERVER_PATH).is_ok_and(|stat| stat.is_file())
34+
}
35+
36+
fn get_lsp_settings_for_worktree(
37+
&mut self,
38+
server_id: &zed::LanguageServerId,
39+
worktree: &zed::Worktree,
40+
) -> Result<Settings> {
41+
let settings = zed::settings::LspSettings::for_worktree(server_id.as_ref(), worktree);
42+
match settings {
43+
Err(_) => Ok(Settings::default()),
44+
Ok(LspSettings { settings: None, .. }) => Ok(Settings::default()),
45+
Ok(LspSettings {
46+
settings: Some(settings_value),
47+
..
48+
}) => Ok(parse_settings(settings_value)),
49+
}
1450
}
1551

1652
fn server_script_path(
1753
&mut self,
1854
server_id: &zed::LanguageServerId,
55+
worktree: &zed::Worktree,
1956
) -> Result<Cow<'static, str>> {
2057
let server_exists = self.server_exists();
2158

@@ -24,24 +61,32 @@ impl ReScriptExtension {
2461
}
2562

2663
zed::set_language_server_installation_status(
27-
&server_id,
64+
server_id,
2865
&zed::LanguageServerInstallationStatus::CheckingForUpdate,
2966
);
30-
let version = zed::npm_package_latest_version(PACKAGE_NAME)?;
67+
let settings = self.get_lsp_settings_for_worktree(server_id, worktree)?;
68+
69+
let version = if let Some(user_version) = settings.version {
70+
user_version
71+
} else {
72+
zed::npm_package_latest_version(PACKAGE_NAME)?
73+
};
3174

3275
if !server_exists
3376
|| zed::npm_package_installed_version(PACKAGE_NAME)?.as_ref() != Some(&version)
3477
{
3578
zed::set_language_server_installation_status(
36-
&server_id,
79+
server_id,
3780
&zed::LanguageServerInstallationStatus::Downloading,
3881
);
3982
let result = zed::npm_install_package(PACKAGE_NAME, &version);
83+
4084
match result {
4185
Ok(()) => {
4286
if !self.server_exists() {
4387
Err(format!(
44-
"installed package '{PACKAGE_NAME}' did not contain expected path '{SERVER_PATH}'",
88+
"installed package '{}' did not contain expected path '{}'",
89+
PACKAGE_NAME, SERVER_PATH
4590
))?;
4691
}
4792
}
@@ -69,9 +114,9 @@ impl zed::Extension for ReScriptExtension {
69114
fn language_server_command(
70115
&mut self,
71116
server_id: &zed::LanguageServerId,
72-
_worktree: &zed::Worktree,
117+
worktree: &zed::Worktree,
73118
) -> Result<zed::Command> {
74-
let server_path = self.server_script_path(server_id)?;
119+
let server_path = self.server_script_path(server_id, worktree)?;
75120

76121
let current_dir = env::current_dir()
77122
.map_err(|e| format!("failed to get current directory: {e}"))?;

0 commit comments

Comments
 (0)