byebug 4.0.5 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +72 -34
  3. data/CONTRIBUTING.md +26 -31
  4. data/README.md +3 -3
  5. data/lib/byebug/breakpoint.rb +2 -1
  6. data/lib/byebug/command.rb +27 -49
  7. data/lib/byebug/commands/break.rb +21 -15
  8. data/lib/byebug/commands/catch.rb +9 -15
  9. data/lib/byebug/commands/condition.rb +12 -15
  10. data/lib/byebug/commands/continue.rb +8 -11
  11. data/lib/byebug/commands/delete.rb +9 -12
  12. data/lib/byebug/commands/disable.rb +32 -0
  13. data/lib/byebug/commands/disable/breakpoints.rb +38 -0
  14. data/lib/byebug/commands/disable/display.rb +39 -0
  15. data/lib/byebug/commands/display.rb +18 -51
  16. data/lib/byebug/commands/down.rb +39 -0
  17. data/lib/byebug/commands/edit.rb +8 -14
  18. data/lib/byebug/commands/enable.rb +25 -0
  19. data/lib/byebug/commands/enable/breakpoints.rb +38 -0
  20. data/lib/byebug/commands/enable/display.rb +39 -0
  21. data/lib/byebug/commands/eval.rb +10 -192
  22. data/lib/byebug/commands/finish.rb +11 -12
  23. data/lib/byebug/commands/frame.rb +17 -182
  24. data/lib/byebug/commands/help.rb +18 -18
  25. data/lib/byebug/commands/history.rb +9 -10
  26. data/lib/byebug/commands/info.rb +17 -190
  27. data/lib/byebug/commands/info/args.rb +39 -0
  28. data/lib/byebug/commands/info/breakpoints.rb +59 -0
  29. data/lib/byebug/commands/info/catch.rb +39 -0
  30. data/lib/byebug/commands/info/display.rb +42 -0
  31. data/lib/byebug/commands/info/file.rb +81 -0
  32. data/lib/byebug/commands/info/line.rb +31 -0
  33. data/lib/byebug/commands/info/program.rb +51 -0
  34. data/lib/byebug/commands/interrupt.rb +5 -9
  35. data/lib/byebug/commands/irb.rb +5 -9
  36. data/lib/byebug/commands/kill.rb +6 -12
  37. data/lib/byebug/commands/list.rb +47 -19
  38. data/lib/byebug/commands/method.rb +8 -14
  39. data/lib/byebug/commands/next.rb +36 -0
  40. data/lib/byebug/commands/pp.rb +41 -0
  41. data/lib/byebug/commands/pry.rb +5 -9
  42. data/lib/byebug/commands/ps.rb +44 -0
  43. data/lib/byebug/commands/putl.rb +43 -0
  44. data/lib/byebug/commands/quit.rb +8 -12
  45. data/lib/byebug/commands/restart.rb +6 -12
  46. data/lib/byebug/commands/save.rb +30 -39
  47. data/lib/byebug/commands/set.rb +19 -21
  48. data/lib/byebug/commands/show.rb +10 -16
  49. data/lib/byebug/commands/source.rb +6 -12
  50. data/lib/byebug/commands/step.rb +36 -0
  51. data/lib/byebug/commands/thread.rb +13 -130
  52. data/lib/byebug/commands/thread/current.rb +35 -0
  53. data/lib/byebug/commands/thread/list.rb +41 -0
  54. data/lib/byebug/commands/thread/resume.rb +45 -0
  55. data/lib/byebug/commands/thread/stop.rb +41 -0
  56. data/lib/byebug/commands/thread/switch.rb +43 -0
  57. data/lib/byebug/commands/tracevar.rb +8 -14
  58. data/lib/byebug/commands/undisplay.rb +12 -15
  59. data/lib/byebug/commands/untracevar.rb +5 -11
  60. data/lib/byebug/commands/up.rb +39 -0
  61. data/lib/byebug/commands/var.rb +15 -94
  62. data/lib/byebug/commands/var/all.rb +37 -0
  63. data/lib/byebug/commands/var/const.rb +38 -0
  64. data/lib/byebug/commands/var/global.rb +33 -0
  65. data/lib/byebug/commands/var/instance.rb +35 -0
  66. data/lib/byebug/commands/var/local.rb +35 -0
  67. data/lib/byebug/commands/where.rb +47 -0
  68. data/lib/byebug/core.rb +10 -0
  69. data/lib/byebug/helpers/eval.rb +47 -0
  70. data/lib/byebug/helpers/file.rb +46 -0
  71. data/lib/byebug/helpers/frame.rb +76 -0
  72. data/lib/byebug/helpers/parse.rb +74 -0
  73. data/lib/byebug/helpers/string.rb +24 -0
  74. data/lib/byebug/helpers/thread.rb +53 -0
  75. data/lib/byebug/helpers/toggle.rb +56 -0
  76. data/lib/byebug/helpers/var.rb +45 -0
  77. data/lib/byebug/history.rb +2 -4
  78. data/lib/byebug/interface.rb +5 -3
  79. data/lib/byebug/interfaces/local_interface.rb +3 -1
  80. data/lib/byebug/interfaces/remote_interface.rb +3 -1
  81. data/lib/byebug/interfaces/test_interface.rb +6 -2
  82. data/lib/byebug/printers/plain.rb +1 -1
  83. data/lib/byebug/processors/command_processor.rb +9 -11
  84. data/lib/byebug/processors/control_command_processor.rb +1 -1
  85. data/lib/byebug/remote.rb +3 -0
  86. data/lib/byebug/runner.rb +5 -3
  87. data/lib/byebug/setting.rb +2 -18
  88. data/lib/byebug/settings/savefile.rb +21 -0
  89. data/lib/byebug/states/regular_state.rb +15 -6
  90. data/lib/byebug/subcommand_list.rb +33 -0
  91. data/lib/byebug/subcommands.rb +53 -0
  92. data/lib/byebug/version.rb +1 -1
  93. metadata +45 -6
  94. data/lib/byebug/commands/enable_disable.rb +0 -132
  95. data/lib/byebug/commands/stepping.rb +0 -75
  96. data/lib/byebug/helper.rb +0 -131
@@ -8,32 +8,32 @@ module Byebug
8
8
  self.allow_in_control = true
9
9
 
10
10
  def regexp
11
- /^\s* h(?:elp)? (?: \s+(\S+) (?:\s+(\S+))? )? \s*$/x
11
+ /^\s* h(?:elp)? (?:\s+(\S+))? (?:\s+(\S+))? \s*$/x
12
12
  end
13
13
 
14
14
  def execute
15
- return puts(self.class.help) unless @match[1]
15
+ return puts(help) unless @match[1]
16
16
 
17
- cmd = Command.commands.select { |c| c.names.include?(@match[1]) }
18
- return errmsg(pr('help.errors.undefined', cmd: @match[1])) unless cmd.any?
17
+ cmd = Byebug.commands.find { |c| c.to_name == @match[1] }
18
+ return errmsg(pr('help.errors.undefined', cmd: @match[1])) unless cmd
19
19
 
20
- cmd.each { |c| puts c.help(@match[2]) }
21
- end
20
+ cmd = cmd.new(@state)
21
+ return puts(cmd.help) unless @match[2]
22
+
23
+ subcmd = cmd.subcommands.find(@match[2])
24
+ return errmsg(pr('help.errors.undefined', cmd: @match[2])) unless subcmd
22
25
 
23
- class << self
24
- def names
25
- %w(help)
26
- end
26
+ puts(subcmd.help)
27
+ end
27
28
 
28
- def description
29
- prettify <<-EOD
30
- h[elp][ <cmd>[ <subcmd>]]
29
+ def description
30
+ <<-EOD
31
+ h[elp][ <cmd>[ <subcmd>]]
31
32
 
32
- help -- prints this help.
33
- help <cmd> -- prints help on command <cmd>.
34
- help <cmd> <subcmd> -- prints help on <cmd>'s subcommand <subcmd>.
35
- EOD
36
- end
33
+ help -- prints this help.
34
+ help <cmd> -- prints help on command <cmd>.
35
+ help <cmd> <subcmd> -- prints help on <cmd>'s subcommand <subcmd>.
36
+ EOD
37
37
  end
38
38
  end
39
39
  end
@@ -1,10 +1,13 @@
1
1
  require 'byebug/command'
2
+ require 'byebug/helpers/parse'
2
3
 
3
4
  module Byebug
4
5
  #
5
6
  # Show history of byebug commands.
6
7
  #
7
8
  class HistoryCommand < Command
9
+ include Helpers::ParseHelper
10
+
8
11
  def regexp
9
12
  /^\s* hist(?:ory)? (?:\s+(?<num_cmds>.+))? \s*$/x
10
13
  end
@@ -13,23 +16,19 @@ module Byebug
13
16
  history = @state.interface.history
14
17
 
15
18
  if @match[:num_cmds]
16
- size, _ = get_int(@match[:num_cmds], 'history', 1, history.size)
19
+ size, = get_int(@match[:num_cmds], 'history', 1, history.size)
17
20
  return errmsg(err) unless size
18
21
  end
19
22
 
20
23
  puts history.to_s(size)
21
24
  end
22
25
 
23
- class << self
24
- def names
25
- %w(history)
26
- end
26
+ def description
27
+ <<-EOD
28
+ hist[ory] [num_cmds]
27
29
 
28
- def description
29
- prettify <<-EOD
30
- hist[ory] [num_cmds] Show byebug's command history.
31
- EOD
32
- end
30
+ Show byebug's command history.
31
+ EOD
33
32
  end
34
33
  end
35
34
  end
@@ -1,205 +1,32 @@
1
- require 'byebug/command'
1
+ require 'byebug/subcommands'
2
2
 
3
- module Byebug
4
- #
5
- # Utilities for the info command.
6
- #
7
- module InfoFunctions
8
- def info_catch(*_args)
9
- return puts('No frame selected.') unless @state.context
10
-
11
- if Byebug.catchpoints && !Byebug.catchpoints.empty?
12
- Byebug.catchpoints.each do |exception, _hits|
13
- puts("#{exception}: #{exception.is_a?(Class)}")
14
- end
15
- else
16
- puts 'No exceptions set to be caught.'
17
- end
18
- end
19
-
20
- def info_args(*args)
21
- locals = @state.context.frame_locals
22
- args = @state.context.frame_args
23
- return if args == [[:rest]]
24
-
25
- args.map do |_, name|
26
- s = "#{name} = #{locals[name].inspect}"
27
- s[Setting[:width] - 3..-1] = '...' if s.size > Setting[:width]
28
- puts s
29
- end
30
- end
31
-
32
- def info_breakpoint(brkpt)
33
- expr = brkpt.expr.nil? ? '' : " if #{brkpt.expr}"
34
- y_n = brkpt.enabled? ? 'y' : 'n'
35
- interp = format('%-3d %-3s at %s:%s%s',
36
- brkpt.id, y_n, brkpt.source, brkpt.pos, expr)
37
- puts interp
38
- hits = brkpt.hit_count
39
- return unless hits > 0
40
-
41
- s = (hits > 1) ? 's' : ''
42
- puts "\tbreakpoint already hit #{hits} time#{s}"
43
- end
44
-
45
- def info_breakpoints(*args)
46
- return puts('No breakpoints.') if Byebug.breakpoints.empty?
47
-
48
- brkpts = Byebug.breakpoints.sort_by(&:id)
49
- unless args.empty?
50
- indices = args.map(&:to_i)
51
- brkpts = brkpts.select { |b| indices.member?(b.id) }
52
- return errmsg('No breakpoints found among list given') if brkpts.empty?
53
- end
54
-
55
- puts 'Num Enb What'
56
- brkpts.each { |b| info_breakpoint(b) }
57
- end
58
-
59
- def info_display(*_args)
60
- return puts('There are no auto-display expressions now.') unless
61
- @state.display.find { |d| d[0] }
62
-
63
- puts 'Auto-display expressions now in effect:'
64
- puts 'Num Enb Expression'
65
- n = 1
66
- @state.display.each do |d|
67
- puts(format('%3d: %s %s', n, d[0] ? 'y' : 'n', d[1]))
68
- n += 1
69
- end
70
- end
71
-
72
- include FileFunctions
73
-
74
- def info_file_basic(file)
75
- path = File.expand_path(file)
76
- return unless File.exist?(path)
77
-
78
- s = n_lines(path) == 1 ? '' : 's'
79
- "#{path} (#{n_lines(path)} line#{s})"
80
- end
81
-
82
- def info_file_breakpoints(file)
83
- breakpoints = Breakpoint.potential_lines(file)
84
- return unless breakpoints
85
-
86
- breakpoints.to_a.sort.columnize(line_prefix: ' ',
87
- displaywidth: Setting[:width])
88
- end
89
-
90
- def info_file_mtime(file)
91
- File.stat(file).mtime
92
- end
93
-
94
- def info_file_sha1(file)
95
- require 'digest/sha1'
96
- Digest::SHA1.hexdigest(file)
97
- end
98
-
99
- def info_line(*_args)
100
- puts "Line #{@state.line} of \"#{@state.file}\""
101
- end
102
-
103
- def info_stop_reason(stop_reason)
104
- case stop_reason
105
- when :step
106
- puts "It stopped after stepping, next'ing or initial start."
107
- when :breakpoint
108
- puts 'It stopped at a breakpoint.'
109
- when :catchpoint
110
- puts 'It stopped at a catchpoint.'
111
- end
112
- end
113
-
114
- def info_program(*_args)
115
- if @state.context.dead?
116
- puts 'The program crashed.'
117
- excpt = Byebug.last_exception
118
- return puts("Exception: #{excpt.inspect}") if excpt
119
- end
120
-
121
- puts 'Program stopped. '
122
- info_stop_reason @state.context.stop_reason
123
- end
124
- end
3
+ require 'byebug/commands/info/args'
4
+ require 'byebug/commands/info/breakpoints'
5
+ require 'byebug/commands/info/catch'
6
+ require 'byebug/commands/info/display'
7
+ require 'byebug/commands/info/file'
8
+ require 'byebug/commands/info/line'
9
+ require 'byebug/commands/info/program'
125
10
 
11
+ module Byebug
126
12
  #
127
- # Show info about different aspects of the debugger.
13
+ # Shows info about different aspects of the debugger.
128
14
  #
129
15
  class InfoCommand < Command
130
- include Columnize
131
- include InfoFunctions
16
+ include Subcommands
132
17
 
133
18
  self.allow_in_control = true
134
19
 
135
- Subcommands = [
136
- ['args', 1, 'Argument variables of current stack frame'],
137
- ['breakpoints', 1, 'Status of user-settable breakpoints',
138
- 'Without argument, list info about all breakpoints. With an integer ' \
139
- 'argument, list info on that breakpoint.'],
140
- ['catch', 3, 'Exceptions that can be caught in the current stack frame'],
141
- ['display', 2, 'Expressions to display when program stops'],
142
- ['file', 4, 'Info about a particular file read in',
143
- 'File name, number of lines, possible breakpoints in the file, last ' \
144
- 'modification time and sha1 digest are listed.'],
145
- ['line', 2, 'Line number and file name of current position in source ' \
146
- 'file.'],
147
- ['program', 2, 'Execution status of the program']
148
- ].map do |name, min, help|
149
- Subcmd.new(name, min, help)
150
- end
151
-
152
- def info_file(*args)
153
- file = args[0] || @state.file
154
- unless File.exist?(file)
155
- return errmsg(pr('info.errors.undefined_file', file: file))
156
- end
157
-
158
- puts <<-EOC.gsub(/^ {6}/, '')
159
-
160
- File #{info_file_basic(file)}
161
-
162
- Breakpoint line numbers:
163
- #{info_file_breakpoints(file)}
164
-
165
- Modification time: #{info_file_mtime(file)}
166
-
167
- Sha1 Signature: #{info_file_sha1(file)}
168
-
169
- EOC
170
- end
171
-
172
20
  def regexp
173
- /^\s* i(?:nfo)? (?:\s+(.+))? \s*$/x
174
- end
175
-
176
- def execute
177
- return puts(self.class.help) unless @match[1]
178
-
179
- args = @match[1].split(/ +/)
180
- param = args.shift
181
- subcmd = Command.find(Subcommands, param)
182
- return errmsg "Unknown info command #{param}\n" unless subcmd
183
-
184
- if @state.context
185
- send("info_#{subcmd.name}", *args)
186
- else
187
- errmsg "'info #{subcmd.name}' not available without a context.\n"
188
- end
21
+ /^\s* i(?:nfo)? (?:\s+ (.+))? \s*$/x
189
22
  end
190
23
 
191
- class << self
192
- def names
193
- %w(info)
194
- end
195
-
196
- def description
197
- prettify <<-EOD
198
- info[ subcommand]
24
+ def description
25
+ <<-EOD
26
+ info[ subcommand]
199
27
 
200
- Generic command for showing things about the program being debugged.
201
- EOD
202
- end
28
+ Generic command for showing things about the program being debugged.
29
+ EOD
203
30
  end
204
31
  end
205
32
  end
@@ -0,0 +1,39 @@
1
+ module Byebug
2
+ #
3
+ # Reopens the +info+ command to define the +args+ subcommand
4
+ #
5
+ class InfoCommand < Command
6
+ #
7
+ # Information about arguments of the current method/block
8
+ #
9
+ class ArgsSubcommand < Command
10
+ def regexp
11
+ /^\s* a(?:rgs)? \s*$/x
12
+ end
13
+
14
+ def execute
15
+ locals = @state.context.frame_locals
16
+ args = @state.context.frame_args
17
+ return if args == [[:rest]]
18
+
19
+ args.map do |_, name|
20
+ s = "#{name} = #{locals[name].inspect}"
21
+ s[Setting[:width] - 3..-1] = '...' if s.size > Setting[:width]
22
+ puts s
23
+ end
24
+ end
25
+
26
+ def short_description
27
+ 'Information about arguments of the current method/block'
28
+ end
29
+
30
+ def description
31
+ <<-EOD
32
+ inf[o] a[args]
33
+
34
+ #{short_description}
35
+ EOD
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,59 @@
1
+ module Byebug
2
+ #
3
+ # Reopens the +info+ command to define the +breakpoints+ subcommand
4
+ #
5
+ class InfoCommand < Command
6
+ #
7
+ # Information about current breakpoints
8
+ #
9
+ class BreakpointsSubcommand < Command
10
+ def regexp
11
+ /^\s* b(?:reakpoints)? (?:\s+ (.+))? \s*$/x
12
+ end
13
+
14
+ def execute
15
+ return puts('No breakpoints.') if Byebug.breakpoints.empty?
16
+
17
+ breakpoints = Byebug.breakpoints.sort_by(&:id)
18
+
19
+ if @match[1]
20
+ indices = @match[1].split(/ +/).map(&:to_i)
21
+ breakpoints = breakpoints.select { |b| indices.member?(b.id) }
22
+ if breakpoints.empty?
23
+ return errmsg('No breakpoints found among list given')
24
+ end
25
+ end
26
+
27
+ puts 'Num Enb What'
28
+ breakpoints.each { |b| info_breakpoint(b) }
29
+ end
30
+
31
+ def short_description
32
+ 'Status of user settable breakpoints.'
33
+ end
34
+
35
+ def description
36
+ <<-EOD
37
+ inf[o] b[reakpoints]
38
+
39
+ #{short_description}
40
+ EOD
41
+ end
42
+
43
+ private
44
+
45
+ def info_breakpoint(brkpt)
46
+ expr = brkpt.expr.nil? ? '' : " if #{brkpt.expr}"
47
+ y_n = brkpt.enabled? ? 'y' : 'n'
48
+ interp = format('%-3d %-3s at %s:%s%s',
49
+ brkpt.id, y_n, brkpt.source, brkpt.pos, expr)
50
+ puts interp
51
+ hits = brkpt.hit_count
52
+ return unless hits > 0
53
+
54
+ s = (hits > 1) ? 's' : ''
55
+ puts "\tbreakpoint already hit #{hits} time#{s}"
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,39 @@
1
+ module Byebug
2
+ #
3
+ # Reopens the +info+ command to define the +catch+ subcommand
4
+ #
5
+ class InfoCommand < Command
6
+ #
7
+ # Information on exceptions that can be caught by the debugger
8
+ #
9
+ class CatchSubcommand < Command
10
+ def regexp
11
+ /^\s* c(?:atch)? (?:\s+ (.+))? \s*$/x
12
+ end
13
+
14
+ def execute
15
+ return puts('No frame selected.') unless @state.context
16
+
17
+ if Byebug.catchpoints && !Byebug.catchpoints.empty?
18
+ Byebug.catchpoints.each do |exception, _hits|
19
+ puts("#{exception}: #{exception.is_a?(Class)}")
20
+ end
21
+ else
22
+ puts 'No exceptions set to be caught.'
23
+ end
24
+ end
25
+
26
+ def short_description
27
+ 'Exceptions that can be caught in the current stack frame'
28
+ end
29
+
30
+ def description
31
+ <<-EOD
32
+ inf[o] c[atch]
33
+
34
+ #{short_description}
35
+ EOD
36
+ end
37
+ end
38
+ end
39
+ end