Skip to content

Commit f88fbc2

Browse files
authored
Merge pull request #11 from nojaf/nojaf
Install lsp server from user configuration.
2 parents b3ce82b + dfa3490 commit f88fbc2

File tree

2 files changed

+74
-7
lines changed

2 files changed

+74
-7
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,28 @@ This extension plugs in the following projects:
77
- [tree-sitter-rescript](https://github.com/rescript-lang/tree-sitter-rescript) parser
88
- [@rescript/language-server](https://github.com/rescript-lang/rescript-vscode) LSP
99

10+
## Settings
11+
12+
```json
13+
"lsp": {
14+
"rescript-language-server": {
15+
"initialization_options": {
16+
"extensionConfiguration": {
17+
"askToStartBuild": false
18+
}
19+
},
20+
"settings": {
21+
"version": "1.71.0-next-441959d.0"
22+
}
23+
}
24+
},
25+
```
26+
27+
`initialization_options` are passed to the language server when it is started. They can be used to configure the language server. See [extensionConfiguration](https://github.com/rescript-lang/rescript-vscode/blob/441959d1feeaaffc1a589687758b1fbe1f649e72/server/src/config.ts#L5-L29)
28+
29+
`settings` are specific to the Zed extension.
30+
With `version` you can point to a specific npm version of the [@rescript/language-server](https://www.npmjs.com/package/@rescript/language-server?activeTab=versions).
31+
1032
## Developing
1133

1234
Zed and it's support for extensions is being actively developed. The current workflow that can be used to build this extension locally and install it into Zed is:

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)