ruby/lib/irb/cmd/subirb.rb
Stan Lo 7f8f62c93b [ruby/irb] Support seamless integration with ruby/debug
(https://github.com/ruby/irb/pull/575)

* Support native integration with ruby/debug

* Prevent using multi-irb and activating debugger at the same time

Multi-irb makes a few assumptions:

- IRB will manage all threads that host sub-irb sessions
- All IRB sessions will be run on the threads created by IRB itself

However, when using the debugger these assumptions are broken:

- `debug` will freeze ALL threads when it suspends the session (e.g. when
  hitting a breakpoint, or performing step-debugging).
- Since the irb-debug integration runs IRB as the debugger's interface,
  it will be run on the debugger's thread, which is not managed by IRB.

So we should prevent the 2 features from being used at the same time.
To do that, we check if the other feature is already activated when
executing the commands that would activate the other feature.

d8fb3246be
2023-08-13 18:30:34 +00:00

109 lines
2.4 KiB
Ruby

# frozen_string_literal: false
#
# multi.rb -
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
require_relative "nop"
module IRB
# :stopdoc:
module ExtendCommand
class MultiIRBCommand < Nop
def execute(*args)
extend_irb_context
end
private
def print_deprecated_warning
warn <<~MSG
Multi-irb commands are deprecated and will be removed in IRB 2.0.0. Please use workspace commands instead.
If you have any use case for multi-irb, please leave a comment at https://github.com/ruby/irb/issues/653
MSG
end
def extend_irb_context
# this extension patches IRB context like IRB.CurrentContext
require_relative "../ext/multi-irb"
end
def print_debugger_warning
warn "Multi-IRB commands are not available when the debugger is enabled."
end
end
class IrbCommand < MultiIRBCommand
category "Multi-irb (DEPRECATED)"
description "Start a child IRB."
def execute(*obj)
print_deprecated_warning
if irb_context.with_debugger
print_debugger_warning
return
end
super
IRB.irb(nil, *obj)
end
end
class Jobs < MultiIRBCommand
category "Multi-irb (DEPRECATED)"
description "List of current sessions."
def execute
print_deprecated_warning
if irb_context.with_debugger
print_debugger_warning
return
end
super
IRB.JobManager
end
end
class Foreground < MultiIRBCommand
category "Multi-irb (DEPRECATED)"
description "Switches to the session of the given number."
def execute(key = nil)
print_deprecated_warning
if irb_context.with_debugger
print_debugger_warning
return
end
super
raise CommandArgumentError.new("Please specify the id of target IRB job (listed in the `jobs` command).") unless key
IRB.JobManager.switch(key)
end
end
class Kill < MultiIRBCommand
category "Multi-irb (DEPRECATED)"
description "Kills the session with the given number."
def execute(*keys)
print_deprecated_warning
if irb_context.with_debugger
print_debugger_warning
return
end
super
IRB.JobManager.kill(*keys)
end
end
end
# :startdoc:
end