lib/pry-byebug/processor.rb in pry-byebug-1.3.3 vs lib/pry-byebug/processor.rb in pry-byebug-2.0.0
- old
+ new
@@ -1,127 +1,105 @@
require 'pry'
require 'byebug'
module PryByebug
+ #
+ # Extends raw byebug's processor.
+ #
class Processor < Byebug::Processor
attr_accessor :pry
def initialize(interface = Byebug::LocalInterface.new)
super(interface)
-
+
Byebug.handler = self
- @always_enabled = true
- @delayed = Hash.new(0)
end
# Wrap a Pry REPL to catch navigational commands and act on them.
- def run(initial = true, &block)
+ def run(initial = false, &_block)
return_value = nil
- command = catch(:breakout_nav) do # Throws from PryByebug::Commands
- return_value = yield
- {} # Nothing thrown == no navigational command
- end
+ if initial
+ Byebug.start
+ Byebug.current_context.step_out(3)
+ else
+ command = catch(:breakout_nav) do # Throws from PryByebug::Commands
+ return_value = yield
+ {} # Nothing thrown == no navigational command
+ end
- times = (command[:times] || 1).to_i # Command argument
- times = 1 if times <= 0
+ times = (command[:times] || 1).to_i # Command argument
+ times = 1 if times <= 0
- if [:step, :next, :finish].include? command[:action]
- @pry = command[:pry] # Pry instance to resume after stepping
- Byebug.start unless Byebug.started?
+ if [:step, :next, :finish].include? command[:action]
+ @pry = command[:pry] # Pry instance to resume after stepping
- if initial
- # Movement when on the initial binding.pry line will have a frame
- # inside Byebug. If we step normally, it'll stop inside this
- # Processor. So jump out and stop at the above frame, then step/next
- # from our callback.
- @delayed[command[:action]] = times
- Byebug.current_context.step_out(2)
- elsif :next == command[:action]
- Byebug.current_context.step_over(times, 0)
+ if :next == command[:action]
+ Byebug.current_context.step_over(times, 0)
- elsif :step == command[:action]
- Byebug.current_context.step_into(times)
+ elsif :step == command[:action]
+ Byebug.current_context.step_into(times)
- elsif :finish == command[:action]
- Byebug.current_context.step_out(0)
+ elsif :finish == command[:action]
+ Byebug.current_context.step_out(times)
+ end
end
- else
- stop
end
return_value
end
- # Adjust debugging. When set to false, the Processor will manage enabling
- # and disabling the debugger itself. When set to true, byebug is always
- # enabled.
- def debugging=(enabled)
- if enabled
- @always_enabled = true
- Byebug.start unless Byebug.started?
- else
- @always_enabled = false
- # Byebug will get stopped if necessary in `stop` once the repl ends.
- end
+ # --- Callbacks from byebug C extension ---
+
+ #
+ # Called when the wants to stop at a regular line
+ #
+ def at_line(context, _file, _line)
+ resume_pry(context)
end
- # --- Callbacks from byebug C extension ---
- def at_line(context, file, line)
- # If any delayed nexts/steps, do 'em.
- if @delayed[:next] > 1
- context.step_over(@delayed[:next] - 1, 0)
+ #
+ # Called when the wants to stop right before a method return
+ #
+ def at_return(context, _file, _line)
+ resume_pry(context)
+ end
- elsif @delayed[:step] > 1
- context.step_into(@delayed[:step] - 1)
+ #
+ # Called when a breakpoint is hit. Note that `at_line`` is called
+ # inmediately after with the context's `stop_reason == :breakpoint`, so we
+ # must not resume the pry instance here
+ #
+ def at_breakpoint(_context, breakpoint)
+ @pry ||= Pry.new
- elsif @delayed[:finish] > 1
- context.step_out(@delayed[:finish] - 1)
+ brkpt_num = "\nBreakpoint #{breakpoint.id}. "
+ @pry.output.print Pry::Helpers::Text.bold(brkpt_num)
- # Otherwise, resume the pry session at the stopped line.
- else
- resume_pry context
- end
+ n_hits = breakpoint.hit_count
+ @pry.output.puts(n_hits == 1 ? 'First hit' : "Hit #{n_hits} times.")
- @delayed = Hash.new(0)
- end
+ expr = breakpoint.expr
+ return unless expr
- # Called when a breakpoint is triggered. Note: `at_line`` is called
- # immediately after with the context's `stop_reason == :breakpoint`.
- def at_breakpoint(context, breakpoint)
- @pry.output.print Pry::Helpers::Text.bold("\nBreakpoint #{breakpoint.id}. ")
- @pry.output.puts (breakpoint.hit_count == 1 ?
- 'First hit.' :
- "Hit #{breakpoint.hit_count} times." )
- if (expr = breakpoint.expr)
- @pry.output.print Pry::Helpers::Text.bold("Condition: ")
- @pry.output.puts expr
- end
+ @pry.output.print Pry::Helpers::Text.bold('Condition: ')
+ @pry.output.puts expr
end
- def at_catchpoint(context, exception)
- # TODO
- end
-
private
- #
- # Resume an existing Pry REPL at the paused point.
- #
- def resume_pry(context)
- new_binding = context.frame_binding(0)
- Byebug.stop unless @always_enabled
+ #
+ # Resume an existing Pry REPL at the paused point.
+ #
+ def resume_pry(context)
+ new_binding = context.frame_binding(0)
- run(false) do
- @pry.repl new_binding
+ run(false) do
+ if @pry
+ @pry.repl(new_binding)
+ else
+ @pry = Pry.start_without_pry_byebug(new_binding)
end
end
-
- # Cleanup when debugging is stopped and execution continues.
- def stop
- Byebug.stop if !@always_enabled && Byebug.started?
- if PryByebug.current_remote_server # Cleanup DRb remote if running
- PryByebug.current_remote_server.teardown
- end
- end
+ end
end
end