@@ -5,10 +5,13 @@ mod language_servers;
55
66use std:: { collections:: HashMap , path:: Path } ;
77
8+ use bundler:: Bundler ;
9+ use command_executor:: RealCommandExecutor ;
10+ use gemset:: Gemset ;
811use language_servers:: { Herb , LanguageServer , Rubocop , RubyLsp , Solargraph , Sorbet , Steep } ;
912use serde:: { Deserialize , Serialize } ;
1013use zed_extension_api:: {
11- self as zed, resolve_tcp_template, Command , DebugAdapterBinary , DebugConfig , DebugRequest ,
14+ self as zed, resolve_tcp_template, DebugAdapterBinary , DebugConfig , DebugRequest ,
1215 DebugScenario , DebugTaskDefinition , StartDebuggingRequestArguments ,
1316 StartDebuggingRequestArgumentsRequest , TcpArgumentsTemplate , Worktree ,
1417} ;
@@ -123,23 +126,31 @@ impl zed::Extension for RubyExtension {
123126 . join ( "rdbg" )
124127 . to_string_lossy ( )
125128 . into_owned ( ) ;
129+ let mut use_bundler = false ;
126130
127131 if worktree. which ( & rdbg_path) . is_none ( ) {
128- match worktree. which ( "rdbg" . as_ref ( ) ) {
129- Some ( path) => rdbg_path = path,
130- None => {
131- let output = Command :: new ( "gem" )
132- . arg ( "install" )
133- . arg ( "--no-document" )
134- . arg ( "--bindir" )
135- . arg ( & adapter_name)
136- . arg ( "debug" )
137- . output ( ) ?;
138- if output. status . is_some_and ( |status| status == 0 ) {
139- return Err ( format ! (
140- "Failed to install rdbg:\n {}" ,
141- String :: from_utf8_lossy( & output. stderr) . into_owned( )
142- ) ) ;
132+ let bundler = Bundler :: new (
133+ worktree. root_path ( ) ,
134+ worktree. shell_env ( ) ,
135+ Box :: new ( RealCommandExecutor ) ,
136+ ) ;
137+ match bundler. installed_gem_version ( "debug" ) {
138+ Ok ( _version) => {
139+ rdbg_path = worktree
140+ . which ( "bundle" )
141+ . ok_or_else ( || "Unable to find 'bundle' command" . to_string ( ) ) ?;
142+ use_bundler = true ;
143+ }
144+ Err ( _e) => {
145+ let gem_home = std:: env:: current_dir ( )
146+ . map_err ( |e| format ! ( "Failed to get extension directory: {e}" ) ) ?
147+ . to_string_lossy ( )
148+ . to_string ( ) ;
149+ let gemset = Gemset :: new ( gem_home. clone ( ) , Box :: new ( RealCommandExecutor ) ) ;
150+
151+ match gemset. install_gem ( "debug" ) {
152+ Ok ( _) => rdbg_path = gemset. gem_bin_path ( "rdbg" ) ?,
153+ Err ( e) => return Err ( format ! ( "Failed to install debug gem: {e}" ) ) ,
143154 }
144155 }
145156 }
@@ -181,12 +192,20 @@ impl zed::Extension for RubyExtension {
181192 }
182193 arguments. extend ( ruby_config. args ) ;
183194
195+ if use_bundler {
196+ arguments. splice ( 0 ..0 , vec ! [ "exec" . to_string( ) , "rdbg" . to_string( ) ] ) ;
197+ }
198+
184199 Ok ( DebugAdapterBinary {
185200 command : Some ( rdbg_path. to_string ( ) ) ,
186201 arguments,
187202 connection : Some ( connection) ,
188203 cwd : ruby_config. cwd ,
189- envs : ruby_config. env . into_iter ( ) . collect ( ) ,
204+ envs : ruby_config
205+ . env
206+ . into_iter ( )
207+ . chain ( std:: iter:: once ( ( "RUBY_DEBUG_OPEN" . into ( ) , "true" . into ( ) ) ) )
208+ . collect ( ) ,
190209 request_args : StartDebuggingRequestArguments {
191210 configuration : configuration. to_string ( ) ,
192211 request : StartDebuggingRequestArgumentsRequest :: Launch ,
0 commit comments