byebug 3.5.1 → 4.0.0

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 (137) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -1
  3. data/.rubocop.yml +18 -1
  4. data/.travis.yml +21 -1
  5. data/CHANGELOG.md +356 -308
  6. data/CONTRIBUTING.md +31 -15
  7. data/GUIDE.md +859 -475
  8. data/Gemfile +8 -10
  9. data/LICENSE +1 -1
  10. data/README.md +41 -45
  11. data/Rakefile +30 -28
  12. data/byebug.gemspec +18 -18
  13. data/ext/byebug/breakpoint.c +88 -75
  14. data/ext/byebug/byebug.c +253 -252
  15. data/ext/byebug/byebug.h +53 -53
  16. data/ext/byebug/context.c +188 -159
  17. data/ext/byebug/extconf.rb +9 -6
  18. data/ext/byebug/locker.c +53 -11
  19. data/ext/byebug/threads.c +137 -39
  20. data/lib/byebug/attacher.rb +7 -2
  21. data/lib/byebug/breakpoint.rb +30 -0
  22. data/lib/byebug/command.rb +36 -32
  23. data/lib/byebug/commands/break.rb +49 -48
  24. data/lib/byebug/commands/catch.rb +64 -0
  25. data/lib/byebug/commands/condition.rb +13 -9
  26. data/lib/byebug/commands/continue.rb +8 -4
  27. data/lib/byebug/commands/delete.rb +10 -4
  28. data/lib/byebug/commands/display.rb +33 -25
  29. data/lib/byebug/commands/edit.rb +18 -13
  30. data/lib/byebug/commands/enable_disable.rb +26 -24
  31. data/lib/byebug/commands/eval.rb +77 -35
  32. data/lib/byebug/commands/finish.rb +9 -5
  33. data/lib/byebug/commands/frame.rb +66 -125
  34. data/lib/byebug/commands/help.rb +14 -21
  35. data/lib/byebug/commands/history.rb +5 -1
  36. data/lib/byebug/commands/info.rb +41 -106
  37. data/lib/byebug/commands/interrupt.rb +6 -2
  38. data/lib/byebug/commands/irb.rb +5 -2
  39. data/lib/byebug/commands/kill.rb +6 -2
  40. data/lib/byebug/commands/list.rb +21 -14
  41. data/lib/byebug/commands/method.rb +17 -9
  42. data/lib/byebug/commands/pry.rb +13 -3
  43. data/lib/byebug/commands/quit.rb +10 -5
  44. data/lib/byebug/commands/restart.rb +12 -19
  45. data/lib/byebug/commands/save.rb +10 -6
  46. data/lib/byebug/commands/set.rb +15 -14
  47. data/lib/byebug/commands/show.rb +8 -8
  48. data/lib/byebug/commands/source.rb +14 -8
  49. data/lib/byebug/commands/stepping.rb +15 -29
  50. data/lib/byebug/commands/threads.rb +73 -49
  51. data/lib/byebug/commands/tracevar.rb +56 -0
  52. data/lib/byebug/commands/undisplay.rb +8 -4
  53. data/lib/byebug/commands/untracevar.rb +38 -0
  54. data/lib/byebug/commands/var.rb +107 -0
  55. data/lib/byebug/context.rb +78 -42
  56. data/lib/byebug/core.rb +78 -40
  57. data/lib/byebug/helper.rb +58 -42
  58. data/lib/byebug/history.rb +12 -1
  59. data/lib/byebug/interface.rb +91 -11
  60. data/lib/byebug/interfaces/local_interface.rb +12 -19
  61. data/lib/byebug/interfaces/remote_interface.rb +12 -15
  62. data/lib/byebug/interfaces/script_interface.rb +14 -18
  63. data/lib/byebug/interfaces/test_interface.rb +54 -0
  64. data/lib/byebug/printers/base.rb +64 -0
  65. data/lib/byebug/printers/plain.rb +53 -0
  66. data/lib/byebug/processor.rb +20 -1
  67. data/lib/byebug/processors/command_processor.rb +57 -172
  68. data/lib/byebug/processors/control_command_processor.rb +16 -43
  69. data/lib/byebug/remote.rb +13 -7
  70. data/lib/byebug/runner.rb +102 -54
  71. data/lib/byebug/setting.rb +45 -68
  72. data/lib/byebug/settings/autoeval.rb +2 -0
  73. data/lib/byebug/settings/autoirb.rb +3 -0
  74. data/lib/byebug/settings/autolist.rb +3 -0
  75. data/lib/byebug/settings/autosave.rb +2 -0
  76. data/lib/byebug/settings/basename.rb +2 -0
  77. data/lib/byebug/settings/callstyle.rb +2 -0
  78. data/lib/byebug/settings/fullpath.rb +2 -0
  79. data/lib/byebug/settings/histfile.rb +2 -0
  80. data/lib/byebug/settings/histsize.rb +2 -0
  81. data/lib/byebug/settings/linetrace.rb +2 -0
  82. data/lib/byebug/settings/listsize.rb +2 -0
  83. data/lib/byebug/settings/post_mortem.rb +7 -2
  84. data/lib/byebug/settings/stack_on_error.rb +2 -0
  85. data/lib/byebug/settings/verbose.rb +2 -0
  86. data/lib/byebug/settings/width.rb +2 -0
  87. data/lib/byebug/state.rb +12 -0
  88. data/lib/byebug/states/control_state.rb +26 -0
  89. data/lib/byebug/states/regular_state.rb +178 -0
  90. data/lib/byebug/version.rb +1 -1
  91. metadata +24 -109
  92. data/lib/byebug/commands/catchpoint.rb +0 -53
  93. data/lib/byebug/commands/reload.rb +0 -29
  94. data/lib/byebug/commands/trace.rb +0 -50
  95. data/lib/byebug/commands/variables.rb +0 -206
  96. data/lib/byebug/options.rb +0 -46
  97. data/lib/byebug/settings/autoreload.rb +0 -12
  98. data/lib/byebug/settings/forcestep.rb +0 -14
  99. data/lib/byebug/settings/testing.rb +0 -12
  100. data/lib/byebug/settings/tracing_plus.rb +0 -11
  101. data/test/commands/break_test.rb +0 -364
  102. data/test/commands/condition_test.rb +0 -85
  103. data/test/commands/continue_test.rb +0 -47
  104. data/test/commands/delete_test.rb +0 -26
  105. data/test/commands/display_test.rb +0 -37
  106. data/test/commands/edit_test.rb +0 -52
  107. data/test/commands/eval_test.rb +0 -89
  108. data/test/commands/finish_test.rb +0 -74
  109. data/test/commands/frame_test.rb +0 -223
  110. data/test/commands/help_test.rb +0 -66
  111. data/test/commands/history_test.rb +0 -61
  112. data/test/commands/info_test.rb +0 -238
  113. data/test/commands/interrupt_test.rb +0 -45
  114. data/test/commands/irb_test.rb +0 -28
  115. data/test/commands/kill_test.rb +0 -50
  116. data/test/commands/list_test.rb +0 -174
  117. data/test/commands/method_test.rb +0 -52
  118. data/test/commands/post_mortem_test.rb +0 -71
  119. data/test/commands/pry_test.rb +0 -26
  120. data/test/commands/quit_test.rb +0 -53
  121. data/test/commands/reload_test.rb +0 -39
  122. data/test/commands/restart_test.rb +0 -46
  123. data/test/commands/save_test.rb +0 -67
  124. data/test/commands/set_test.rb +0 -140
  125. data/test/commands/show_test.rb +0 -76
  126. data/test/commands/source_test.rb +0 -46
  127. data/test/commands/stepping_test.rb +0 -192
  128. data/test/commands/thread_test.rb +0 -164
  129. data/test/commands/trace_test.rb +0 -71
  130. data/test/commands/undisplay_test.rb +0 -75
  131. data/test/commands/variables_test.rb +0 -105
  132. data/test/debugger_alias_test.rb +0 -7
  133. data/test/runner_test.rb +0 -150
  134. data/test/support/matchers.rb +0 -65
  135. data/test/support/test_interface.rb +0 -59
  136. data/test/support/utils.rb +0 -122
  137. data/test/test_helper.rb +0 -58
@@ -1,12 +1,14 @@
1
+ require 'byebug/command'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Mixin to assist command parsing
4
6
  #
5
7
  module EnableDisableFunctions
6
8
  def enable_disable_breakpoints(is_enable, args)
7
- return errmsg('No breakpoints have been set') if Breakpoint.none?
9
+ return errmsg(pr('toggle.errors.no_breakpoints')) if Breakpoint.none?
8
10
 
9
- all_breakpoints = Byebug.breakpoints.sort_by { |b| b.id }
11
+ all_breakpoints = Byebug.breakpoints.sort_by(&:id)
10
12
  if args.empty?
11
13
  selected_breakpoints = all_breakpoints
12
14
  else
@@ -18,16 +20,15 @@ module Byebug
18
20
 
19
21
  selected_ids << pos
20
22
  end
21
- selected_breakpoints = all_breakpoints.select do
22
- |b| selected_ids.include?(b.id)
23
+ selected_breakpoints = all_breakpoints.select do |b|
24
+ selected_ids.include?(b.id)
23
25
  end
24
26
  end
25
27
 
26
28
  selected_breakpoints.each do |b|
27
29
  enabled = ('enable' == is_enable)
28
30
  if enabled && !syntax_valid?(b.expr)
29
- return errmsg("Expression \"#{b.expr}\" syntactically incorrect; " \
30
- 'breakpoint remains disabled.')
31
+ return errmsg(pr('toggle.errors.expression', expr: b.expr))
31
32
  end
32
33
 
33
34
  b.enabled = enabled
@@ -35,9 +36,7 @@ module Byebug
35
36
  end
36
37
 
37
38
  def enable_disable_display(is_enable, args)
38
- if 0 == @state.display.size
39
- return errmsg('No display expressions have been set')
40
- end
39
+ return errmsg(pr('toggle.errors.no_display')) if 0 == @state.display.size
41
40
 
42
41
  args.each do |pos|
43
42
  pos, err = get_int(pos, "#{is_enable} display", 1, @state.display.size)
@@ -52,6 +51,8 @@ module Byebug
52
51
  # Enabling or disabling custom display expressions or breakpoints.
53
52
  #
54
53
  class EnableDisableCommand < Command
54
+ include EnableDisableFunctions
55
+
55
56
  Subcommands = [
56
57
  ['breakpoints', 2, 'Enable/disable breakpoints. Give breakpoint ' \
57
58
  'numbers (separated by spaces) as arguments or no ' \
@@ -64,7 +65,7 @@ module Byebug
64
65
  'numbers']
65
66
  ].map do |name, min, help|
66
67
  Subcmd.new(name, min, help)
67
- end unless defined?(Subcommands)
68
+ end
68
69
 
69
70
  def regexp
70
71
  /^\s* (dis|en)(?:able)? (?:\s+(.+))? \s*$/x
@@ -73,8 +74,7 @@ module Byebug
73
74
  def execute
74
75
  cmd = @match[1] == 'dis' ? 'disable' : 'enable'
75
76
 
76
- return errmsg("\"#{cmd}\" must be followed by \"display\", " \
77
- "\"breakpoints\" or breakpoint ids") unless @match[2]
77
+ return errmsg(pr('toggle.errors.syntax', toggle: cmd)) unless @match[2]
78
78
 
79
79
  args = @match[2].split(/[ \t]+/)
80
80
  param = args.shift
@@ -108,22 +108,24 @@ module Byebug
108
108
  end
109
109
 
110
110
  def description
111
- %{(en|dis)[able][[ (breakpoints|display)][ n1[ n2[ ...[ nn]]]]]
111
+ prettify <<-EOD
112
+ (en|dis)[able][[ (breakpoints|display)][ n1[ n2[ ...[ nn]]]]]
112
113
 
113
- Enables or disables breakpoints or displays.
114
+ Enables or disables breakpoints or displays.
114
115
 
115
- "enable" by itself enables all breakpoints, just like
116
- "enable breakpoints". On the other side, "disable" or
117
- "disable breakpoints" disable all breakpoints.
116
+ "enable" by itself enables all breakpoints, just like
117
+ "enable breakpoints". On the other side, "disable" or
118
+ "disable breakpoints" disable all breakpoints.
118
119
 
119
- You can also specify a space separated list of breakpoint numbers to
120
- enable or disable specific breakpoints. You can use either
121
- "enable <id1> ... <idn>" or "enable breakpoints <id1> ... <idn>" and
122
- the same with "disable".
120
+ You can also specify a space separated list of breakpoint numbers to
121
+ enable or disable specific breakpoints. You can use either
122
+ "enable <id1> ... <idn>" or "enable breakpoints <id1> ... <idn>" and
123
+ the same with "disable".
123
124
 
124
- If instead of "breakpoints" you specify "display", the command will
125
- work exactly the same way, but displays will get enabled/disabled
126
- instead of breakpoints.}
125
+ If instead of "breakpoints" you specify "display", the command will
126
+ work exactly the same way, but displays will get enabled/disabled
127
+ instead of breakpoints.
128
+ EOD
127
129
  end
128
130
  end
129
131
  end
@@ -1,3 +1,5 @@
1
+ require 'byebug/command'
2
+
1
3
  require 'English'
2
4
  require 'pp'
3
5
 
@@ -6,16 +8,52 @@ module Byebug
6
8
  # Utilities used by the eval command
7
9
  #
8
10
  module EvalFunctions
11
+ #
12
+ # Run block temporarily ignoring all TracePoint events.
13
+ #
14
+ # Used to evaluate stuff within Byebug's prompt. Otherwise, any code
15
+ # creating new threads won't be properly evaluated because new threads will
16
+ # get blocked by byebug's main thread.
17
+ #
18
+ def allowing_other_threads
19
+ Byebug.unlock
20
+ res = yield
21
+ Byebug.lock
22
+ res
23
+ end
24
+
25
+ #
26
+ # Get current binding and yield it to the given block
27
+ #
9
28
  def run_with_binding
10
29
  binding = get_binding
11
30
  yield binding
12
31
  end
32
+
33
+ #
34
+ # Evaluate +expression+ using +binding+
35
+ #
36
+ # @param binding [Binding] Context where to evaluate the expression
37
+ # @param expression [String] Expression to evaluation
38
+ # @param stack_on_error [Boolean] Whether to show a stack trace on error.
39
+ #
40
+ def eval_with_setting(binding, expression, stack_on_error)
41
+ allowing_other_threads do
42
+ if stack_on_error
43
+ bb_eval(expression, binding)
44
+ else
45
+ bb_warning_eval(expression, binding)
46
+ end
47
+ end
48
+ end
13
49
  end
14
50
 
15
51
  #
16
52
  # Evaluation of expressions from byebug's prompt.
17
53
  #
18
54
  class EvalCommand < Command
55
+ include EvalFunctions
56
+
19
57
  self.allow_in_control = true
20
58
 
21
59
  def match(input)
@@ -24,17 +62,15 @@ module Byebug
24
62
  end
25
63
 
26
64
  def regexp
27
- /^\s* (p|e(?:val)?)\s+/x
65
+ /^\s* e(?:val)? \s+/x
28
66
  end
29
67
 
30
68
  def execute
31
69
  expr = @match ? @match.post_match : @input
32
70
  run_with_binding do |b|
33
- if Setting[:stack_on_error]
34
- puts "#{bb_eval(expr, b).inspect}"
35
- else
36
- puts "#{bb_warning_eval(expr, b).inspect}"
37
- end
71
+ res = eval_with_setting(b, expr, Setting[:stack_on_error])
72
+
73
+ print pr('eval.result', expr: expr, result: res.inspect)
38
74
  end
39
75
  rescue
40
76
  puts "#{$ERROR_INFO.class} Exception: #{$ERROR_INFO.message}"
@@ -42,16 +78,18 @@ module Byebug
42
78
 
43
79
  class << self
44
80
  def names
45
- %w(p eval)
81
+ %w(eval)
46
82
  end
47
83
 
48
84
  def description
49
- %{(p|e[val]) <expression>
85
+ prettify <<-EOD
86
+ e[val] <expression>
50
87
 
51
88
  Evaluates <expression> and prints its value.
52
89
 
53
90
  * NOTE - unknown input is automatically evaluated, to turn this off
54
- use 'set noautoeval'.}
91
+ use 'set noautoeval'.
92
+ EOD
55
93
  end
56
94
  end
57
95
  end
@@ -60,6 +98,8 @@ module Byebug
60
98
  # Evaluation and pretty printing from byebug's prompt.
61
99
  #
62
100
  class PPCommand < Command
101
+ include EvalFunctions
102
+
63
103
  self.allow_in_control = true
64
104
 
65
105
  def regexp
@@ -86,9 +126,11 @@ module Byebug
86
126
  end
87
127
 
88
128
  def description
89
- %(pp <expression>
129
+ prettify <<-EOD
130
+ pp <expression>
90
131
 
91
- Evaluates <expression> and pretty-prints its value.)
132
+ Evaluates <expression> and pretty-prints its value.
133
+ EOD
92
134
  end
93
135
  end
94
136
  end
@@ -97,26 +139,24 @@ module Byebug
97
139
  # Evaluation, pretty printing and columnizing from byebug's prompt.
98
140
  #
99
141
  class PutLCommand < Command
142
+ include EvalFunctions
100
143
  include Columnize
144
+
101
145
  self.allow_in_control = true
102
146
 
103
147
  def regexp
104
- /^\s* putl\s+/x
148
+ /^\s* putl \s+/x
105
149
  end
106
150
 
107
151
  def execute
108
152
  out = StringIO.new
109
153
  run_with_binding do |b|
110
- if Setting[:stack_on_error]
111
- vals = bb_eval(@match.post_match, b)
112
- else
113
- vals = bb_warning_eval(@match.post_match, b)
114
- end
115
- if vals.is_a?(Array)
116
- vals = vals.map { |item| item.to_s }
117
- puts "#{columnize(vals, Setting[:width])}"
154
+ res = eval_with_setting(b, @match.post_match, Setting[:stack_on_error])
155
+
156
+ if res.is_a?(Array)
157
+ puts "#{columnize(res.map(&:to_s), Setting[:width])}"
118
158
  else
119
- PP.pp(vals, out)
159
+ PP.pp(res, out)
120
160
  puts out.string
121
161
  end
122
162
  end
@@ -130,9 +170,11 @@ module Byebug
130
170
  end
131
171
 
132
172
  def description
133
- %(putl <expression>
173
+ prettify <<-EOD
174
+ putl <expression>
134
175
 
135
- Evaluates <expression>, an array, and columnize its value.)
176
+ Evaluates <expression>, an array, and columnize its value.
177
+ EOD
136
178
  end
137
179
  end
138
180
  end
@@ -141,26 +183,24 @@ module Byebug
141
183
  # Evaluation, pretty printing, columnizing and sorting from byebug's prompt
142
184
  #
143
185
  class PSCommand < Command
186
+ include EvalFunctions
144
187
  include Columnize
188
+
145
189
  self.allow_in_control = true
146
190
 
147
191
  def regexp
148
- /^\s* ps\s+/x
192
+ /^\s* ps \s+/x
149
193
  end
150
194
 
151
195
  def execute
152
196
  out = StringIO.new
153
197
  run_with_binding do |b|
154
- if Setting[:stack_on_error]
155
- vals = bb_eval(@match.post_match, b)
156
- else
157
- vals = bb_warning_eval(@match.post_match, b)
158
- end
159
- if vals.is_a?(Array)
160
- vals = vals.map { |item| item.to_s }
161
- puts "#{columnize(vals.sort!, Setting[:width])}"
198
+ res = eval_with_setting(b, @match.post_match, Setting[:stack_on_error])
199
+
200
+ if res.is_a?(Array)
201
+ puts "#{columnize(res.map(&:to_s).sort!, Setting[:width])}"
162
202
  else
163
- PP.pp(vals, out)
203
+ PP.pp(res, out)
164
204
  puts out.string
165
205
  end
166
206
  end
@@ -174,9 +214,11 @@ module Byebug
174
214
  end
175
215
 
176
216
  def description
177
- %(ps <expression>
217
+ prettify <<-EOD
218
+ ps <expression>
178
219
 
179
- Evaluates <expression>, an array, sort and columnize its value.)
220
+ Evaluates <expression>, an array, sort and columnize its value.
221
+ EOD
180
222
  end
181
223
  end
182
224
  end
@@ -1,3 +1,5 @@
1
+ require 'byebug/command'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Implements the finish functionality.
@@ -12,7 +14,7 @@ module Byebug
12
14
  end
13
15
 
14
16
  def execute
15
- max_frames = Context.stack_size - @state.frame_pos
17
+ max_frames = @state.context.stack_size - @state.frame
16
18
  if @match[1]
17
19
  n_frames, err = get_int(@match[1], 'finish', 0, max_frames - 1)
18
20
  return errmsg(err) unless n_frames
@@ -21,8 +23,8 @@ module Byebug
21
23
  end
22
24
 
23
25
  force = n_frames == 0 ? true : false
24
- @state.context.step_out(@state.frame_pos + n_frames, force)
25
- @state.frame_pos = 0
26
+ @state.context.step_out(@state.frame + n_frames, force)
27
+ @state.frame = 0
26
28
  @state.proceed
27
29
  end
28
30
 
@@ -32,11 +34,13 @@ module Byebug
32
34
  end
33
35
 
34
36
  def description
35
- %(fin[ish][ n_frames] Execute until frame returns.
37
+ prettify <<-EOD
38
+ fin[ish][ n_frames] Execute until frame returns.
36
39
 
37
40
  If no number is given, we run until the current frame returns. If a
38
41
  number of frames `n_frames` is given, then we run until `n_frames`
39
- return from the current position.)
42
+ return from the current position.
43
+ EOD
40
44
  end
41
45
  end
42
46
  end
@@ -1,26 +1,28 @@
1
+ require 'byebug/command'
2
+
1
3
  # encoding: utf-8
4
+
5
+ require 'pathname'
6
+
2
7
  module Byebug
3
8
  #
4
9
  # Mixin to assist command parsing
5
10
  #
6
11
  module FrameFunctions
7
- def c_frame?(frame_no)
8
- @state.context.frame_binding(frame_no).nil?
9
- end
10
-
11
12
  def switch_to_frame(frame_no)
12
- frame_no >= 0 ? frame_no : Context.stack_size + frame_no
13
+ frame_no >= 0 ? frame_no : @state.context.stack_size + frame_no
13
14
  end
14
15
 
15
16
  def navigate_to_frame(jump_no)
16
17
  return if jump_no == 0
17
- total_jumps, current_jumps, new_pos = jump_no.abs, 0, @state.frame_pos
18
- step = jump_no / total_jumps
18
+ total_jumps, current_jumps, new_pos = jump_no.abs, 0, @state.frame
19
+ step = jump_no / total_jumps # +1 (up) or -1 (down)
20
+
19
21
  loop do
20
22
  new_pos += step
21
- return new_pos if new_pos < 0 || new_pos >= Context.stack_size
23
+ break if new_pos < 0 || new_pos >= @state.context.stack_size
22
24
 
23
- next if c_frame?(new_pos)
25
+ next if @state.c_frame?(new_pos)
24
26
 
25
27
  current_jumps += 1
26
28
  break if current_jumps == total_jumps
@@ -28,126 +30,36 @@ module Byebug
28
30
  new_pos
29
31
  end
30
32
 
31
- def adjust_frame(frame_pos, absolute)
33
+ def adjust_frame(frame, absolute)
32
34
  if absolute
33
- abs_frame_pos = switch_to_frame(frame_pos)
34
- return errmsg("Can't navigate to c-frame") if c_frame?(abs_frame_pos)
35
+ abs_frame = switch_to_frame(frame)
36
+ return errmsg(pr('frame.errors.c_frame')) if @state.c_frame?(abs_frame)
35
37
  else
36
- abs_frame_pos = navigate_to_frame(frame_pos)
38
+ abs_frame = navigate_to_frame(frame)
37
39
  end
38
40
 
39
- if abs_frame_pos >= Context.stack_size
40
- return errmsg("Can't navigate beyond the oldest frame")
41
- elsif abs_frame_pos < 0
42
- return errmsg("Can't navigate beyond the newest frame")
41
+ if abs_frame >= @state.context.stack_size
42
+ return errmsg(pr('frame.errors.too_low'))
43
+ elsif abs_frame < 0
44
+ return errmsg(pr('frame.errors.too_high'))
43
45
  end
44
46
 
45
- @state.frame_pos = abs_frame_pos
46
- @state.file = @state.context.frame_file @state.frame_pos
47
- @state.line = @state.context.frame_line @state.frame_pos
47
+ @state.frame = abs_frame
48
+ @state.file = @state.context.frame_file(@state.frame)
49
+ @state.line = @state.context.frame_line(@state.frame)
48
50
  @state.prev_line = nil
49
- ListCommand.new(@state).execute
50
- end
51
-
52
- def get_frame_class(style, pos)
53
- frame_class = style == 'short' ? '' : "#{@state.context.frame_class pos}"
54
- frame_class == '' ? '' : "#{frame_class}."
55
- end
56
-
57
- def get_frame_block_and_method(pos)
58
- frame_deco_regexp = /((?:block(?: \(\d+ levels\))?|rescue) in )?(.+)/
59
- frame_deco_method = "#{@state.context.frame_method pos}"
60
- frame_block_and_method = frame_deco_regexp.match(frame_deco_method)[1..2]
61
- frame_block_and_method.map { |x| x.nil? ? '' : x }
62
- end
63
-
64
- def get_frame_args(style, pos)
65
- args = @state.context.frame_args pos
66
- return '' if args.empty?
67
-
68
- locals = @state.context.frame_locals pos if style == 'long'
69
- my_args = args.map do |arg|
70
- case arg[0]
71
- when :block
72
- prefix, default = '&', 'block'
73
- when :rest
74
- prefix, default = '*', 'args'
75
- else
76
- prefix, default = '', nil
77
- end
78
-
79
- klass = style == 'long' && arg[1] ? "##{locals[arg[1]].class}" : ''
80
- "#{prefix}#{arg[1] || default}#{klass}"
81
- end
82
-
83
- "(#{my_args.join(', ')})"
84
- end
85
-
86
- def get_frame_call(prefix, pos)
87
- frame_block, frame_method = get_frame_block_and_method(pos)
88
- frame_class = get_frame_class(Setting[:callstyle], pos)
89
- frame_args = get_frame_args(Setting[:callstyle], pos)
90
-
91
- call_str = frame_block + frame_class + frame_method + frame_args
92
-
93
- max_call_str_size = Setting[:width] - prefix.size
94
- if call_str.size > max_call_str_size
95
- call_str = call_str[0..max_call_str_size - 5] + '...)'
96
- end
97
-
98
- call_str
99
- end
100
-
101
- def print_backtrace
102
- realsize = Context.stack_size
103
- calcedsize = @state.context.calced_stack_size
104
- if calcedsize != realsize
105
- if Byebug.post_mortem?
106
- stacksize = calcedsize
107
- else
108
- errmsg "Byebug's stacksize (#{calcedsize}) should be #{realsize}. " \
109
- "This might be a bug in byebug or ruby's debugging API's\n"
110
- stacksize = realsize
111
- end
112
- else
113
- stacksize = calcedsize
114
- end
115
- (0...stacksize).each do |idx|
116
- print_frame(idx)
117
- end
118
- end
119
-
120
- require 'pathname'
121
-
122
- def shortpath(fullpath)
123
- components = Pathname(fullpath).each_filename.to_a
124
- return File.join(components) if components.size <= 2
125
51
 
126
- File.join('...', components[-3..-1])
52
+ ListCommand.new(@state).execute if Setting[:autolist]
127
53
  end
128
54
 
129
- def print_frame(pos, mark_current = true)
130
- fullpath = @state.context.frame_file(pos)
131
- file = Setting[:fullpath] ? fullpath : shortpath(fullpath)
132
- line = @state.context.frame_line(pos)
133
-
134
- if mark_current
135
- frame_str = (pos == @state.frame_pos) ? '--> ' : ' '
136
- else
137
- frame_str = ''
138
- end
139
- frame_str += c_frame?(pos) ? ' ͱ-- ' : ''
140
-
141
- frame_str += format('#%-2d ', pos)
142
- frame_str += get_frame_call frame_str, pos
143
- file_line = "at #{CommandProcessor.canonic_file(file)}:#{line}"
144
- if frame_str.size + file_line.size + 1 > Setting[:width]
145
- frame_str += "\n #{file_line}"
146
- else
147
- frame_str += " #{file_line}"
148
- end
55
+ def get_pr_arguments(frame_no)
56
+ file = @state.frame_file(frame_no)
57
+ line = @state.frame_line(frame_no)
58
+ call = @state.frame_call(frame_no)
59
+ mark = @state.frame_mark(frame_no)
60
+ pos = @state.frame_pos(frame_no)
149
61
 
150
- puts frame_str
62
+ { mark: mark, pos: pos, call: call, file: file, line: line }
151
63
  end
152
64
  end
153
65
 
@@ -155,6 +67,8 @@ module Byebug
155
67
  # Show current backtrace.
156
68
  #
157
69
  class WhereCommand < Command
70
+ include FrameFunctions
71
+
158
72
  def regexp
159
73
  /^\s* (?:w(?:here)?|bt|backtrace) \s*$/x
160
74
  end
@@ -169,22 +83,36 @@ module Byebug
169
83
  end
170
84
 
171
85
  def description
172
- %(w[here]|bt|backtrace Display stack frames.
86
+ prettify <<-EOD
87
+ w[here]|bt|backtrace Display stack frames.
173
88
 
174
89
  Print the entire stack frame. Each frame is numbered; the most recent
175
90
  frame is 0. A frame number can be referred to in the "frame" command;
176
91
  "up" and "down" add or subtract respectively to frame numbers shown.
177
92
  The position of the current frame is marked with -->. C-frames hang
178
93
  from their most immediate Ruby frame to indicate that they are not
179
- navigable.)
94
+ navigable.
95
+ EOD
180
96
  end
181
97
  end
98
+
99
+ private
100
+
101
+ def print_backtrace
102
+ bt = prc('frame.line', (0...@state.context.stack_size)) do |_, index|
103
+ get_pr_arguments(index)
104
+ end
105
+
106
+ print(bt)
107
+ end
182
108
  end
183
109
 
184
110
  #
185
111
  # Move the current frame up in the backtrace.
186
112
  #
187
113
  class UpCommand < Command
114
+ include FrameFunctions
115
+
188
116
  def regexp
189
117
  /^\s* u(?:p)? (?:\s+(\S+))? \s*$/x
190
118
  end
@@ -202,7 +130,9 @@ module Byebug
202
130
  end
203
131
 
204
132
  def description
205
- %(up[ count] Move to higher frame.)
133
+ prettify <<-EOD
134
+ up[ count] Move to higher frame.
135
+ EOD
206
136
  end
207
137
  end
208
138
  end
@@ -211,6 +141,8 @@ module Byebug
211
141
  # Move the current frame down in the backtrace.
212
142
  #
213
143
  class DownCommand < Command
144
+ include FrameFunctions
145
+
214
146
  def regexp
215
147
  /^\s* down (?:\s+(\S+))? \s*$/x
216
148
  end
@@ -228,7 +160,9 @@ module Byebug
228
160
  end
229
161
 
230
162
  def description
231
- %(down[ count] Move to lower frame.)
163
+ prettify <<-EOD
164
+ down[ count] Move to lower frame.
165
+ EOD
232
166
  end
233
167
  end
234
168
  end
@@ -237,12 +171,17 @@ module Byebug
237
171
  # Move to specific frames in the backtrace.
238
172
  #
239
173
  class FrameCommand < Command
174
+ include FrameFunctions
175
+
240
176
  def regexp
241
177
  /^\s* f(?:rame)? (?:\s+(\S+))? \s*$/x
242
178
  end
243
179
 
244
180
  def execute
245
- return print_frame @state.frame_pos unless @match[1]
181
+ unless @match[1]
182
+ print(pr('frame.line', get_pr_arguments(@state.frame)))
183
+ return
184
+ end
246
185
 
247
186
  pos, err = get_int(@match[1], 'Frame')
248
187
  return errmsg(err) unless pos
@@ -256,7 +195,8 @@ module Byebug
256
195
  end
257
196
 
258
197
  def description
259
- %(f[rame][ frame-number]
198
+ prettify <<-EOD
199
+ f[rame][ frame-number]
260
200
 
261
201
  Move the current frame to the specified frame number, or the 0 if no
262
202
  frame-number has been given.
@@ -267,7 +207,8 @@ module Byebug
267
207
 
268
208
  Without an argument, the command prints the current stack frame. Since
269
209
  the current position is redisplayed, it may trigger a resyncronization
270
- if there is a front end also watching over things.)
210
+ if there is a front end also watching over things.
211
+ EOD
271
212
  end
272
213
  end
273
214
  end