@@ -6,6 +6,7 @@ use zed_extension_api::{
6
6
pub struct LanguageServerBinary {
7
7
pub path : String ,
8
8
pub args : Option < Vec < String > > ,
9
+ pub env : Option < Vec < ( String , String ) > > ,
9
10
}
10
11
11
12
pub trait LanguageServer {
@@ -31,7 +32,7 @@ pub trait LanguageServer {
31
32
Ok ( zed:: Command {
32
33
command : binary. path ,
33
34
args : binary. args . unwrap_or ( Self :: get_executable_args ( ) ) ,
34
- env : Default :: default ( ) ,
35
+ env : binary . env . unwrap_or_default ( ) ,
35
36
} )
36
37
}
37
38
@@ -40,19 +41,14 @@ pub trait LanguageServer {
40
41
language_server_id : & LanguageServerId ,
41
42
worktree : & zed:: Worktree ,
42
43
) -> Result < LanguageServerBinary > {
43
- let output = Command :: new ( "ls" ) . output ( ) ?;
44
-
45
- dbg ! ( & output. status) ;
46
- dbg ! ( String :: from_utf8_lossy( & output. stdout) . to_string( ) ) ;
47
- dbg ! ( String :: from_utf8_lossy( & output. stderr) . to_string( ) ) ;
48
-
49
44
let lsp_settings = LspSettings :: for_worktree ( language_server_id. as_ref ( ) , worktree) ?;
50
45
51
46
if let Some ( binary_settings) = lsp_settings. binary {
52
47
if let Some ( path) = binary_settings. path {
53
48
return Ok ( LanguageServerBinary {
54
49
path,
55
50
args : binary_settings. arguments ,
51
+ env : Default :: default ( ) ,
56
52
} ) ;
57
53
}
58
54
}
@@ -75,16 +71,58 @@ pub trait LanguageServer {
75
71
]
76
72
. concat ( ) ,
77
73
) ,
74
+ env : Default :: default ( ) ,
78
75
} )
79
76
. ok_or_else ( || "Unable to find the 'bundle' command." . into ( ) )
80
77
} else {
81
- worktree
82
- . which ( Self :: EXECUTABLE_NAME )
83
- . map ( |path| LanguageServerBinary {
84
- path,
78
+ let gem_home = std:: env:: current_dir ( )
79
+ . map_err ( |e| format ! ( "Failed to get current directory: {}" , e) ) ?
80
+ . to_string_lossy ( )
81
+ . to_string ( ) ;
82
+
83
+ // Check if the gem is already installed
84
+ if let Some ( existing_binary) = worktree. which ( Self :: EXECUTABLE_NAME ) {
85
+ return Ok ( LanguageServerBinary {
86
+ path : existing_binary,
85
87
args : Some ( Self :: get_executable_args ( ) ) ,
86
- } )
87
- . ok_or_else ( || format ! ( "Unable to find the '{}' command." , Self :: EXECUTABLE_NAME ) )
88
+ env : Some ( vec ! [ (
89
+ "GEM_PATH" . to_string( ) ,
90
+ format!( "{}:$GEM_PATH" , gem_home) ,
91
+ ) ] ) ,
92
+ } ) ;
93
+ }
94
+
95
+ let output = Command :: new ( "gem" )
96
+ . env ( "GEM_HOME" , gem_home. clone ( ) )
97
+ . arg ( "install" )
98
+ . arg ( "--no-user-install" )
99
+ . arg ( "--no-format-executable" )
100
+ . arg ( "--no-document" )
101
+ . arg ( Self :: GEM_NAME )
102
+ . output ( ) ?;
103
+
104
+ let stderr_output = String :: from_utf8_lossy ( & output. stderr ) . to_string ( ) ;
105
+
106
+ match output. status {
107
+ Some ( 0 ) => Ok ( LanguageServerBinary {
108
+ path : format ! ( "{}/bin/{}" , gem_home, Self :: EXECUTABLE_NAME ) ,
109
+ args : Some ( Self :: get_executable_args ( ) ) ,
110
+ env : Some ( vec ! [ (
111
+ "GEM_PATH" . to_string( ) ,
112
+ format!( "{}:$GEM_PATH" , gem_home) ,
113
+ ) ] ) ,
114
+ } ) ,
115
+ Some ( status) => Err ( format ! (
116
+ "Failed to install {} gem (status: {})\n Error: {}" ,
117
+ Self :: GEM_NAME ,
118
+ status,
119
+ stderr_output
120
+ ) ) ,
121
+ None => Err ( format ! (
122
+ "Failed to start language server: {}" ,
123
+ stderr_output
124
+ ) ) ,
125
+ }
88
126
}
89
127
}
90
128
}
0 commit comments