pry-moves 0.1.13 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +9 -5
  4. data/README.md +25 -9
  5. data/lib/commands/debug.rb +21 -0
  6. data/lib/commands/finish.rb +26 -0
  7. data/lib/commands/goto.rb +19 -0
  8. data/lib/commands/iterate.rb +22 -0
  9. data/lib/commands/next.rb +37 -0
  10. data/lib/commands/next_breakpoint.rb +22 -0
  11. data/lib/commands/step.rb +83 -0
  12. data/lib/commands/trace_command.rb +87 -0
  13. data/lib/commands/trace_helpers.rb +49 -0
  14. data/lib/commands/traced_method.rb +71 -0
  15. data/lib/debug_sugar.rb +73 -0
  16. data/lib/pry-moves/add_suffix.rb +87 -0
  17. data/lib/pry-moves/backtrace.rb +99 -50
  18. data/lib/pry-moves/bindings_stack.rb +106 -0
  19. data/lib/pry-moves/commands.rb +42 -3
  20. data/lib/pry-moves/error_with_data.rb +10 -0
  21. data/lib/pry-moves/formatter.rb +79 -0
  22. data/lib/pry-moves/painter.rb +3 -2
  23. data/lib/pry-moves/pry_ext.rb +66 -18
  24. data/lib/pry-moves/pry_wrapper.rb +30 -17
  25. data/lib/pry-moves/recursion_tracker.rb +94 -0
  26. data/lib/pry-moves/restartable.rb +39 -0
  27. data/lib/pry-moves/version.rb +1 -1
  28. data/lib/pry-moves/watch.rb +3 -0
  29. data/lib/pry-moves.rb +77 -6
  30. data/lib/pry-stack_explorer/frame_helpers.rb +114 -0
  31. data/lib/pry-stack_explorer/frame_manager.rb +6 -9
  32. data/lib/pry-stack_explorer/pry-stack_explorer.rb +2 -17
  33. data/lib/pry-stack_explorer/{commands.rb → stack_commands.rb} +6 -109
  34. data/lib/pry-stack_explorer/when_started_hook.rb +10 -65
  35. data/playground/Gemfile.lock +9 -5
  36. data/playground/README.md +1 -0
  37. data/playground/playground.rb +94 -9
  38. data/playground/sand.rb +12 -10
  39. data/playground/test.rb +5 -1
  40. data/playground/test.sh +1 -0
  41. data/pry-moves.gemspec +4 -2
  42. data/publish.sh +2 -1
  43. data/spec/backtrace_spec.rb +11 -13
  44. data/spec/blocks_spec.rb +41 -8
  45. data/spec/commands_spec.rb +26 -25
  46. data/spec/pry_debugger.rb +5 -1
  47. data/spec/redirection_spec.rb +7 -0
  48. data/spec/spec_helper.rb +9 -4
  49. data/spec/step_spec.rb +51 -0
  50. metadata +60 -13
  51. data/lib/pry-moves/helpers.rb +0 -56
  52. data/lib/pry-moves/trace_commands.rb +0 -109
  53. data/lib/pry-moves/traced_method.rb +0 -61
  54. data/lib/pry-moves/tracer.rb +0 -140
  55. data/lib/pry-moves/traversing.rb +0 -69
@@ -1,32 +1,32 @@
1
1
  class << Pry
2
- alias_method :start_without_pry_nav, :start
3
-
4
- def start_with_pry_nav(target = TOPLEVEL_BINDING, options = {})
5
- old_options = options.reject { |k, _| k == :pry_remote }
2
+ alias pry_moves_origin_start start
6
3
 
4
+ def start(target = TOPLEVEL_BINDING, options = {})
7
5
  if target.is_a?(Binding) && PryMoves.check_file_context(target)
8
6
  # Wrap the tracer around the usual Pry.start
9
- PryMoves::PryWrapper.new(target, options).run do
10
- start_without_pry_nav(target, old_options)
11
- end
7
+ original_verbosity = $VERBOSE
8
+ $VERBOSE = nil # Disable warnings for pry-moves
9
+ PryMoves::PryWrapper.new(target, options, self).run
10
+ $VERBOSE = original_verbosity
12
11
  else
13
12
  # No need for the tracer unless we have a file context to step through
14
- start_without_pry_nav(target, old_options)
13
+ pry_moves_origin_start(target, options)
15
14
  end
16
15
  end
17
16
 
18
- alias_method :start, :start_with_pry_nav
19
17
  end
20
18
 
21
19
  Binding.class_eval do
22
20
 
21
+ attr_accessor :index, :hidden
22
+
23
23
  alias pry_forced pry
24
24
 
25
- def pry
26
- unless Pry.config.disable_breakpoints
27
- PryMoves.synchronize_threads ||
28
- return # Don't start binding.pry when semaphore locked by current thread
29
- pry_forced
25
+ def pry options = nil
26
+ if !Pry.config.disable_breakpoints and
27
+ # Don't start binding.pry when semaphore locked by current thread
28
+ PryMoves.synchronize_threads
29
+ pry_forced options
30
30
  end
31
31
  end
32
32
 
@@ -34,6 +34,32 @@ end
34
34
 
35
35
  Pry.config.pager = false
36
36
 
37
+ Pry::Command.class_eval do
38
+ class << self
39
+ attr_accessor :original_user_input
40
+ end
41
+
42
+ alias run_origin_for_pry_moves run
43
+ def run(command_string, *args)
44
+ Pry.config.original_user_input = self.class.original_user_input
45
+ result = run_origin_for_pry_moves command_string, *args
46
+ Pry.config.original_user_input = nil
47
+ result
48
+ end
49
+ end
50
+
51
+ Pry::CommandSet.class_eval do
52
+
53
+ alias alias_command_origin_for_pry_moves alias_command
54
+
55
+ def alias_command(match, action, options = {})
56
+ cmd = alias_command_origin_for_pry_moves match, action, options
57
+ cmd.original_user_input = match
58
+ cmd
59
+ end
60
+
61
+ end
62
+
37
63
  Pry::Command::Whereami.class_eval do
38
64
  # Negligent function from Pry - evidently poor output format
39
65
  # would be wanted to be changed often by developers,
@@ -56,11 +82,19 @@ Pry::Command::Whereami.class_eval do
56
82
  end
57
83
 
58
84
  def build_output
59
- lines = []
60
- lines << "#{text.bold('From:')} #{PryMoves::Helpers.shorten_path location}"
61
- lines << PryMoves::Watch.instance.output(target) unless PryMoves::Watch.instance.empty?
85
+ lines = ['']
86
+
87
+ formatter = PryMoves::Formatter.new
88
+ prefix = Thread.current[:pry_moves_debug] ? "👾 " : ""
89
+ lines << "#{prefix}#{formatter.shorten_path location}"
90
+ lines << " ." + formatter.method_signature(target)
62
91
  lines << ''
63
92
  lines << "#{code.with_line_numbers(use_line_numbers?).with_marker(marker).highlighted}"
93
+
94
+ lines << PryMoves::Watch.instance.output(target) unless PryMoves::Watch.instance.empty?
95
+ lines.concat PryMoves.messages
96
+ PryMoves.messages.clear
97
+
64
98
  lines << ''
65
99
  lines.join "\n"
66
100
  end
@@ -82,4 +116,18 @@ Pry::Code::LOC.class_eval do
82
116
  tuple[0] = " #{marker} #{ line }"
83
117
  end
84
118
 
85
- end
119
+ end
120
+
121
+ Pry::Output.class_eval do
122
+
123
+ alias pry_moves_origin_for_puts puts
124
+
125
+ def puts *args
126
+ first = args[0]
127
+ if first.is_a? String and first.start_with? "(pry) output error"
128
+ first.slice! 400..-1
129
+ end
130
+ pry_moves_origin_for_puts *args
131
+ end
132
+
133
+ end if defined? Pry::Output
@@ -2,24 +2,24 @@ require 'pry' unless defined? Pry
2
2
 
3
3
  module PryMoves
4
4
  class PryWrapper
5
- def initialize(binding_, pry_start_options = {})
5
+ def initialize(binding_, pry_start_options, pry)
6
6
  @init_binding = binding_
7
7
  @pry_start_options = pry_start_options # Options to use for Pry.start
8
+ @pry = pry
8
9
  end
9
10
 
10
- def run(&block)
11
+ def run
11
12
  PryMoves.lock
12
13
 
13
- Pry.config.marker = "⛔️" if @pry_start_options[:exit_from_method]
14
-
15
- return_value = nil
16
- PryMoves.is_open = true
17
- @command = catch(:breakout_nav) do # Coordinates with PryMoves::Commands
18
- return_value = yield
19
- nil # Nothing thrown == no navigational command
14
+ initial_frame = PryMoves::BindingsStack.new(@pry_start_options).initial_frame
15
+ if not @pry_start_options[:pry_moves_loop] and
16
+ initial_frame.local_variable_defined? :debug_redirect
17
+ debug_redirect = initial_frame.local_variable_get(:debug_redirect)
18
+ PryMoves.messages << "⏩ redirected to #{debug_redirect}"
19
+ @command = {action: :step, binding: initial_frame}
20
+ else
21
+ start_pry
20
22
  end
21
- PryMoves.is_open = false
22
- Pry.config.marker = "=>"
23
23
 
24
24
  if @command
25
25
  trace_command
@@ -30,11 +30,24 @@ class PryWrapper
30
30
  end
31
31
  end
32
32
 
33
- return_value
33
+ @return_value
34
34
  end
35
35
 
36
36
  private
37
37
 
38
+ def start_pry
39
+ Pry.config.marker = "⛔️" if @pry_start_options[:exit_from_method]
40
+ PryMoves.is_open = true
41
+
42
+ @command = catch(:breakout_nav) do # Coordinates with PryMoves::Commands
43
+ @return_value = @pry.pry_moves_origin_start(@init_binding, @pry_start_options)
44
+ nil # Nothing thrown == no navigational command
45
+ end
46
+
47
+ PryMoves.is_open = false
48
+ Pry.config.marker = "=>"
49
+ end
50
+
38
51
  def trace_command
39
52
  if @command[:action] == :debug
40
53
  wrap_debug
@@ -61,9 +74,9 @@ class PryWrapper
61
74
  tracer = start_tracing
62
75
  begin
63
76
  @command[:binding].eval @command[:param]
64
- rescue => e
77
+ rescue StandardError, SyntaxError => e
65
78
  Thread.current.set_trace_func nil
66
- puts e
79
+ puts "❌️ Error during #{"debug".yellow} execution: #{e}"
67
80
  end
68
81
  tracer.stop_tracing
69
82
  end.join
@@ -73,9 +86,9 @@ class PryWrapper
73
86
 
74
87
  def start_tracing
75
88
  @last_runtime_binding = @command[:binding]
76
- tracer = PryMoves::Tracer.new @command, @pry_start_options
77
- tracer.trace
78
- tracer
89
+ PryMoves::TraceCommand.trace @command, @pry_start_options do |binding|
90
+ Pry.start(binding, @pry_start_options)
91
+ end
79
92
  end
80
93
 
81
94
  end
@@ -0,0 +1,94 @@
1
+ module PryMoves::Recursion
2
+
3
+ class Tracker
4
+
5
+ attr_reader :loops
6
+
7
+ def initialize
8
+ @history = []
9
+ @loops = 0
10
+ @missing = 0
11
+ @currently_missing = []
12
+ @missing_lines = []
13
+ end
14
+
15
+ def track file, line_num, bt_index, binding_index
16
+ line = "#{file}:#{line_num}"
17
+ if @last_index
18
+ check_recursion line, bt_index, binding_index
19
+ elsif (prev_index = @history.rindex line)
20
+ @loops += 1
21
+ @last_index = prev_index
22
+ @recursion_size = 1
23
+ else
24
+ @history << line
25
+ @last_index = nil
26
+ end
27
+
28
+ @repetitions_start ||= bt_index if @loops == 2
29
+ end
30
+
31
+ def check_recursion line, bt_index, binding_index
32
+ prev_index = @history.rindex line
33
+ if prev_index == @last_index
34
+ @loops += 1
35
+ @missing = 0
36
+ @recursion_size = 0
37
+ @missing_lines.concat @currently_missing
38
+ @repetitions_end = bt_index
39
+ elsif prev_index && prev_index > @last_index
40
+ @last_index = prev_index + 1
41
+ @recursion_size += 1
42
+ # todo: finish tracking and debug multi-line recursions
43
+ elsif @missing <= @recursion_size
44
+ @missing += 1
45
+ @currently_missing << binding_index
46
+ false
47
+ else
48
+ # @missing_lines = nil
49
+ # @last_index = nil
50
+ @is_finished = true
51
+ false
52
+ end
53
+ end
54
+
55
+ def finished?
56
+ @is_finished
57
+ end
58
+
59
+ def good?
60
+ @repetitions_start and @repetitions_end
61
+ end
62
+
63
+ def apply result
64
+ label = "♻️ recursion with #{@loops} loops"
65
+ label += " Ⓜ️ #{@missing} missing lines #{@missing_lines}" if @missing_lines.present?
66
+ label = "...(#{label})..."
67
+ # puts "#{@repetitions_start}..#{@repetitions_end}"
68
+ result[@repetitions_start..@repetitions_end] = [label]
69
+ end
70
+
71
+ end
72
+
73
+ class Holder < Array
74
+
75
+ def initialize(*args)
76
+ super
77
+ new_tracker
78
+ end
79
+
80
+ def new_tracker
81
+ @tracker = Tracker.new
82
+ end
83
+
84
+ def track *args
85
+ @tracker.track *args
86
+ if @tracker.finished?
87
+ self << @tracker if @tracker.good?
88
+ new_tracker
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+ end
@@ -0,0 +1,39 @@
1
+ module PryMoves::Restartable
2
+
3
+ attr_accessor :restart_requested, :reload_requested,
4
+ :reload_rake_tasks
5
+
6
+ def restartable context
7
+ trigger :each_new_run, context
8
+ yield
9
+ re_execution
10
+ rescue PryMoves::Restart
11
+ puts "🔄️ Restarting execution"
12
+ self.restart_requested = false
13
+ PryMoves.reset
14
+ trigger :restart, context
15
+ retry
16
+ rescue PryMoves::Reload
17
+ puts "🔮 try to use @ with reload"
18
+ exit 3
19
+ end
20
+
21
+ def re_execution
22
+ raise PryMoves::Restart if restart_requested
23
+ raise PryMoves::Reload if reload_requested
24
+ end
25
+
26
+
27
+ end
28
+
29
+ class PryMoves::Restart < RuntimeError
30
+ end
31
+ class PryMoves::Reload < RuntimeError
32
+ end
33
+ RSpec::Support::AllExceptionsExceptOnesWeMustNotRescue::AVOID_RESCUING.concat [PryMoves::Restart, PryMoves::Reload] if defined? RSpec
34
+
35
+ Pry.config.hooks.add_hook(:after_eval, :exit_on_re_execution) do |_, _, _pry_|
36
+ if PryMoves.restart_requested or PryMoves.reload_requested
37
+ Pry.run_command 'exit-all'
38
+ end
39
+ end
@@ -1,3 +1,3 @@
1
1
  module PryMoves
2
- VERSION = '0.1.13'
2
+ VERSION = '1.0.2'
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require 'singleton'
2
+ require 'set'
2
3
 
3
4
  class PryMoves::Watch
4
5
 
@@ -44,6 +45,8 @@ class PryMoves::Watch
44
45
  "\033[1m#{cmd}\033[0m: #{format binding_.eval(cmd)}"
45
46
  rescue NameError
46
47
  "\033[1m#{cmd}\033[0m: <undefined>"
48
+ rescue => e
49
+ "\033[1m#{cmd}\033[0m: <#{e}>"
47
50
  end
48
51
 
49
52
  def format(text)
data/lib/pry-moves.rb CHANGED
@@ -1,19 +1,34 @@
1
1
  require 'pry' unless defined? Pry
2
+ require 'colorize'
3
+ require 'diffy'
2
4
 
3
5
  require 'pry-moves/version'
4
- require 'pry-moves/trace_commands'
5
- require 'pry-moves/traced_method'
6
- require 'pry-moves/tracer'
7
6
  require 'pry-moves/pry_ext'
8
7
  require 'pry-moves/commands'
9
- require 'pry-moves/traversing'
8
+ require 'pry-moves/add_suffix'
10
9
  require 'pry-moves/pry_wrapper'
10
+ require 'pry-moves/bindings_stack'
11
+ require 'pry-moves/formatter'
11
12
  require 'pry-moves/backtrace'
12
13
  require 'pry-moves/watch'
13
- require 'pry-moves/helpers'
14
14
  require 'pry-moves/painter'
15
+ require 'pry-moves/restartable'
16
+ require 'pry-moves/recursion_tracker'
17
+ require 'pry-moves/error_with_data'
18
+
19
+ require 'commands/traced_method'
20
+ require 'commands/trace_helpers'
21
+ require 'commands/trace_command'
22
+ require 'commands/debug'
23
+ require 'commands/finish'
24
+ require 'commands/goto'
25
+ require 'commands/iterate'
26
+ require 'commands/next'
27
+ require 'commands/next_breakpoint'
28
+ require 'commands/step'
15
29
 
16
30
  require 'pry-stack_explorer/pry-stack_explorer'
31
+ require 'debug_sugar'
17
32
 
18
33
  # Optionally load pry-remote monkey patches
19
34
  require 'pry-moves/pry_remote_ext' if defined? PryRemote
@@ -22,8 +37,36 @@ module PryMoves
22
37
  TRACE_IGNORE_FILES = Dir[File.join(File.dirname(__FILE__), '**', '*.rb')].map { |f| File.expand_path(f) }
23
38
 
24
39
  extend self
40
+ extend PryMoves::Restartable
41
+
42
+ attr_accessor :is_open, :trace, :stack_tips,
43
+ :stop_on_breakpoints, :launched_specs_examples, :debug_called_times
25
44
 
26
- attr_accessor :is_open
45
+ def reset
46
+ self.launched_specs_examples = 0
47
+ self.stop_on_breakpoints = true
48
+ self.debug_called_times = 0
49
+ end
50
+
51
+ def debug(message = nil, at: nil, options: nil)
52
+ pry_moves_stack_end = true
53
+ PryMoves.re_execution
54
+ if PryMoves.stop_on_breakpoints
55
+ self.debug_called_times += 1
56
+ if at
57
+ return unless self.debug_called_times == at
58
+ end
59
+ if message
60
+ PryMoves.messages << (message.is_a?(String) ? message : message.ai)
61
+ end
62
+ binding.pry options
63
+ PryMoves.re_execution
64
+ end
65
+ end
66
+
67
+ def error(message)
68
+ debug message, options: {is_error: true}
69
+ end
27
70
 
28
71
  # Checks that a binding is in a local file context. Extracted from
29
72
  # https://github.com/pry/pry/blob/master/lib/pry/default_commands/context.rb
@@ -36,9 +79,18 @@ module PryMoves
36
79
  @semaphore ||= Mutex.new
37
80
  end
38
81
 
82
+ def messages
83
+ @messages ||= []
84
+ end
85
+
86
+ def add_command(command, &block)
87
+ Pry.commands.block_command command, "", &block
88
+ end
89
+
39
90
  def locked?
40
91
  semaphore.locked?
41
92
  end
93
+ alias tracing? locked?
42
94
 
43
95
  def lock
44
96
  semaphore.lock unless semaphore.locked?
@@ -59,6 +111,25 @@ module PryMoves
59
111
  true
60
112
  end
61
113
 
114
+ def trigger(event, context)
115
+ triggers[event].each {|t| t.call context}
116
+ end
117
+
118
+ def triggers
119
+ @triggers ||= Hash.new do |hash, key|
120
+ hash[key] = []
121
+ end
122
+ end
123
+
124
+ TRIGGERS = [:each_new_run, :restart]
125
+ def on(trigger, &block)
126
+ error "Invalid trigger, possible triggers: #{TRIGGERS}", trigger unless trigger.in? TRIGGERS
127
+ triggers[trigger] << block
128
+ end
129
+
62
130
  # Reference to currently running pry-remote server. Used by the tracer.
63
131
  attr_accessor :current_remote_server
64
132
  end
133
+
134
+ PryMoves.reset
135
+ PryMoves.trace = true if ENV['TRACE_MOVES']
@@ -0,0 +1,114 @@
1
+ module PryStackExplorer; end
2
+ module PryStackExplorer::FrameHelpers
3
+ private
4
+
5
+ # @return [PryStackExplorer::FrameManager] The active frame manager for
6
+ # the current `Pry` instance.
7
+ def frame_manager
8
+ PryStackExplorer.frame_manager(_pry_)
9
+ end
10
+
11
+ # @return [Array<PryStackExplorer::FrameManager>] All the frame
12
+ # managers for the current `Pry` instance.
13
+ def frame_managers
14
+ PryStackExplorer.frame_managers(_pry_)
15
+ end
16
+
17
+ # @return [Boolean] Whether there is a context to return to once
18
+ # the current `frame_manager` is popped.
19
+ def prior_context_exists?
20
+ frame_managers.count > 1 || frame_manager.prior_binding
21
+ end
22
+
23
+ # Return a description of the frame (binding).
24
+ # This is only useful for regular old bindings that have not been
25
+ # enhanced by `#of_caller`.
26
+ # @param [Binding] b The binding.
27
+ # @return [String] A description of the frame (binding).
28
+ def frame_description(b)
29
+ b_self = b.eval('self')
30
+ b_method = b.eval('__method__')
31
+
32
+ if b_method && b_method != :__binding__ && b_method != :__binding_impl__
33
+ b_method.to_s
34
+ elsif b_self.instance_of?(Module)
35
+ "<module:#{b_self}>"
36
+ elsif b_self.instance_of?(Class)
37
+ "<class:#{b_self}>"
38
+ else
39
+ "<main>"
40
+ end
41
+ end
42
+
43
+ # Return a description of the passed binding object. Accepts an
44
+ # optional `verbose` parameter.
45
+ # @param [Binding] b The binding.
46
+ # @param [Boolean] verbose Whether to generate a verbose description.
47
+ # @return [String] The description of the binding.
48
+ def frame_info(b, verbose = false)
49
+ b_self = b.eval('self')
50
+ type = b.frame_type ? "[#{b.frame_type}]".ljust(9) : ""
51
+ desc = b.frame_description ? "#{b.frame_description}" : "#{frame_description(b)}"
52
+ sig = PryMoves::Formatter.new.method_signature b
53
+
54
+ self_clipped = "#{Pry.view_clip(b_self)}"
55
+ path = "@ #{b.eval('__FILE__')}:#{b.eval('__LINE__')}"
56
+
57
+ if !verbose
58
+ "#{type} #{desc} #{sig}"
59
+ else
60
+ "#{type} #{desc} #{sig}\n in #{self_clipped} #{path}"
61
+ end
62
+ end
63
+
64
+ def find_frame_by_regex(regex, up_or_down)
65
+ frame_index = find_frame_by_block(up_or_down) do |b|
66
+ (b.eval('"#{__FILE__}:#{__LINE__}"') =~ regex) or
67
+ (b.eval("__method__").to_s =~ regex)
68
+ end
69
+
70
+ frame_index || raise(Pry::CommandError, "No frame that matches #{regex.source} found")
71
+ end
72
+
73
+ def find_frame_by_block(up_or_down)
74
+ start_index = frame_manager.binding_index
75
+
76
+ if up_or_down == :down
77
+ enum = start_index == 0 ? [].each :
78
+ frame_manager.bindings[0..start_index - 1].reverse_each
79
+ else
80
+ enum = frame_manager.bindings[start_index + 1..-1]
81
+ end
82
+
83
+ new_frame = enum.find do |b|
84
+ yield(b)
85
+ end
86
+
87
+ frame_manager.bindings.index(new_frame)
88
+ end
89
+
90
+ def find_frame_by_direction(dir, step_into_vapid: false)
91
+ frame_index = find_frame_by_block(dir) do |b|
92
+ step_into_vapid or not b.hidden
93
+ end
94
+
95
+ if !frame_index and !step_into_vapid
96
+ frame_index = find_frame_by_block(dir) {true}
97
+ end
98
+
99
+ frame_index ||
100
+ raise(Pry::CommandError, "At #{dir == :up ? 'top' : 'bottom'} of stack, cannot go further")
101
+ end
102
+
103
+ def move(direction, param)
104
+ raise Pry::CommandError, "Nowhere to go" unless frame_manager
105
+
106
+ if param == '+' or param.nil?
107
+ index = find_frame_by_direction direction, step_into_vapid: param == '+'
108
+ frame_manager.change_frame_to index
109
+ else
110
+ index = find_frame_by_regex(Regexp.new(param), direction)
111
+ frame_manager.change_frame_to index
112
+ end
113
+ end
114
+ end
@@ -33,13 +33,6 @@ module PryStackExplorer
33
33
  @prior_backtrace = _pry_.backtrace
34
34
  end
35
35
 
36
- def filter_bindings(vapid_frames: false)
37
- bindings.reject do |binding|
38
- !vapid_frames and
39
- binding.local_variable_defined?(:vapid_frame)
40
- end
41
- end
42
-
43
36
  # Iterate over all frames
44
37
  def each(&block)
45
38
  bindings.each(&block)
@@ -61,14 +54,18 @@ module PryStackExplorer
61
54
  # @param [Fixnum] index The index.
62
55
  def set_binding_index_safely(index)
63
56
  if index > bindings.size - 1
64
- raise Pry::CommandError, "At top of stack, cannot go further"
57
+ raise Pry::CommandError, "Shouldn't happen: At top of stack, cannot go further"
65
58
  elsif index < 0
66
- raise Pry::CommandError, "At bottom of stack, cannot go further"
59
+ raise Pry::CommandError, "Shouldn't happen: At bottom of stack, cannot go further"
67
60
  else
68
61
  self.binding_index = index
69
62
  end
70
63
  end
71
64
 
65
+ def goto_index index
66
+ change_frame_to bindings.index {|b| b.index == index }
67
+ end
68
+
72
69
  # Change active frame to the one indexed by `index`.
73
70
  # Note that indexing base is `0`
74
71
  # @param [Fixnum] index The index of the frame.
@@ -1,7 +1,7 @@
1
1
  # pry-stack_explorer.rb
2
2
  # (C) John Mair (banisterfiend); MIT license
3
3
 
4
- require "pry-stack_explorer/commands"
4
+ require "pry-stack_explorer/stack_commands"
5
5
  require "pry-stack_explorer/frame_manager"
6
6
  require "pry-stack_explorer/when_started_hook"
7
7
  require "binding_of_caller"
@@ -121,20 +121,5 @@ end
121
121
  Pry.config.hooks.add_hook(:when_started, :save_caller_bindings, PryStackExplorer::WhenStartedHook.new)
122
122
 
123
123
  # Import the StackExplorer commands
124
- Pry.config.commands.import PryStackExplorer::Commands
124
+ Pry.config.commands.import PryStackExplorer::COMMANDS
125
125
 
126
- # monkey-patch the whereami command to show some frame information,
127
- # useful for navigating stack.
128
- Pry.config.hooks.add_hook(:before_whereami, :stack_explorer) do
129
- if PryStackExplorer.frame_manager(_pry_) && !internal_binding?(target)
130
- bindings = PryStackExplorer.frame_manager(_pry_).bindings
131
- binding_index = PryStackExplorer.frame_manager(_pry_).binding_index
132
-
133
- info = "#{Pry::Helpers::Text.bold('Frame:')} "+
134
- "#{binding_index}/#{bindings.size - 1} "+
135
- "#{bindings[binding_index].frame_type}"
136
-
137
- output.puts "\n"
138
- output.puts info
139
- end
140
- end