11use std:: { borrow:: Cow , env, fs} ;
2+ use zed_extension_api:: serde_json:: Value ;
3+ use zed_extension_api:: settings:: LspSettings ;
24use zed_extension_api:: { self as zed, Result } ;
35
46const 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+
1131impl 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