debug 1.5.0 → 1.6.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.
@@ -14,10 +14,19 @@ module DEBUGGER__
14
14
  def initialize
15
15
  # cache
16
16
  @cmap = ObjectSpace::WeakMap.new
17
+ @loaded_file_map = {} # path => nil
17
18
  end
18
19
 
19
20
  def add iseq, src
20
21
  # do nothing
22
+ if (path = (iseq.absolute_path || iseq.path)) && File.exist?(path)
23
+ if @loaded_file_map.has_key? path
24
+ return path, true # reloaded
25
+ else
26
+ @loaded_file_map[path] = path
27
+ return path, false
28
+ end
29
+ end
21
30
  end
22
31
 
23
32
  def get iseq
@@ -55,10 +64,14 @@ module DEBUGGER__
55
64
 
56
65
  def add iseq, src
57
66
  if (path = (iseq.absolute_path || iseq.path)) && File.exist?(path)
67
+ reloaded = @files.has_key? path
58
68
  add_path path
69
+ return path, reloaded
59
70
  elsif src
60
71
  add_iseq iseq, src
61
72
  end
73
+
74
+ nil
62
75
  end
63
76
 
64
77
  private def all_iseq iseq, rs = []
@@ -6,9 +6,26 @@ require 'pp'
6
6
  require_relative 'color'
7
7
 
8
8
  module DEBUGGER__
9
+ M_INSTANCE_VARIABLES = method(:instance_variables).unbind
10
+ M_INSTANCE_VARIABLE_GET = method(:instance_variable_get).unbind
11
+ M_CLASS = method(:class).unbind
12
+ M_SINGLETON_CLASS = method(:singleton_class).unbind
13
+ M_KIND_OF_P = method(:kind_of?).unbind
14
+ M_RESPOND_TO_P = method(:respond_to?).unbind
15
+ M_METHOD = method(:method).unbind
16
+ M_OBJECT_ID = method(:object_id).unbind
17
+
9
18
  module SkipPathHelper
10
19
  def skip_path?(path)
11
- !path || skip_internal_path?(path) || (skip_paths = CONFIG[:skip_path]) && skip_paths.any?{|skip_path| path.match?(skip_path)}
20
+ !path ||
21
+ CONFIG.skip? ||
22
+ ThreadClient.current.management? ||
23
+ skip_internal_path?(path) ||
24
+ skip_config_skip_path?(path)
25
+ end
26
+
27
+ def skip_config_skip_path?(path)
28
+ (skip_paths = CONFIG[:skip_path]) && skip_paths.any?{|skip_path| path.match?(skip_path)}
12
29
  end
13
30
 
14
31
  def skip_internal_path?(path)
@@ -34,7 +51,7 @@ module DEBUGGER__
34
51
  include Color
35
52
  include SkipPathHelper
36
53
 
37
- attr_reader :thread, :id, :recorder
54
+ attr_reader :thread, :id, :recorder, :check_bp_fulfillment_map
38
55
 
39
56
  def location
40
57
  current_frame&.location
@@ -50,7 +67,8 @@ module DEBUGGER__
50
67
  call_identifier_str =
51
68
  case frame.frame_type
52
69
  when :block
53
- level, block_loc, args = frame.block_identifier
70
+ level, block_loc = frame.block_identifier
71
+ args = frame.parameters_info
54
72
 
55
73
  if !args.empty?
56
74
  args_str = " {|#{assemble_arguments(args)}|}"
@@ -58,7 +76,8 @@ module DEBUGGER__
58
76
 
59
77
  "#{colorize_blue("block")}#{args_str} in #{colorize_blue(block_loc + level)}"
60
78
  when :method
61
- ci, args = frame.method_identifier
79
+ ci = frame.method_identifier
80
+ args = frame.parameters_info
62
81
 
63
82
  if !args.empty?
64
83
  args_str = "(#{assemble_arguments(args)})"
@@ -95,6 +114,9 @@ module DEBUGGER__
95
114
  @obj_map = {} # { object_id => obj } for CDP
96
115
  @recorder = nil
97
116
  @mode = :waiting
117
+ @current_frame_index = 0
118
+ # every thread should maintain its own CheckBreakpoint fulfillment state
119
+ @check_bp_fulfillment_map = {} # { check_bp => boolean }
98
120
  set_mode :running
99
121
  thr.instance_variable_set(:@__thread_client_id, id)
100
122
 
@@ -114,6 +136,7 @@ module DEBUGGER__
114
136
  end
115
137
 
116
138
  def set_mode mode
139
+ debug_mode(@mode, mode)
117
140
  # STDERR.puts "#{@mode} => #{mode} @ #{caller.inspect}"
118
141
  # pp caller
119
142
 
@@ -177,6 +200,7 @@ module DEBUGGER__
177
200
  end
178
201
 
179
202
  def << req
203
+ debug_cmd(req)
180
204
  @q_cmd << req
181
205
  end
182
206
 
@@ -187,6 +211,7 @@ module DEBUGGER__
187
211
  end
188
212
 
189
213
  def event! ev, *args
214
+ debug_event(ev, args)
190
215
  @q_evt << [self, @output, ev, generate_info, *args]
191
216
  @output = []
192
217
  end
@@ -232,6 +257,7 @@ module DEBUGGER__
232
257
 
233
258
  def suspend event, tp = nil, bp: nil, sig: nil, postmortem_frames: nil, replay_frames: nil, postmortem_exc: nil
234
259
  return if management?
260
+ debug_suspend(event)
235
261
 
236
262
  @current_frame_index = 0
237
263
 
@@ -266,7 +292,7 @@ module DEBUGGER__
266
292
 
267
293
  if event != :pause
268
294
  show_src
269
- show_frames CONFIG[:show_frames] || 2
295
+ show_frames CONFIG[:show_frames]
270
296
 
271
297
  set_mode :waiting
272
298
 
@@ -413,55 +439,64 @@ module DEBUGGER__
413
439
  raise if re_raise
414
440
  end
415
441
 
416
- def show_src(frame_index: @current_frame_index,
417
- update_line: false,
418
- max_lines: CONFIG[:show_src_lines] || 10,
419
- start_line: nil,
420
- end_line: nil,
421
- dir: +1)
422
- if @target_frames && frame = @target_frames[frame_index]
423
- if file_lines = frame.file_lines
424
- frame_line = frame.location.lineno - 1
425
-
426
- lines = file_lines.map.with_index do |e, i|
427
- cur = i == frame_line ? '=>' : ' '
428
- line = colorize_dim('%4d|' % (i+1))
429
- "#{cur}#{line} #{e}"
430
- end
442
+ def get_src(frame,
443
+ max_lines:,
444
+ start_line: nil,
445
+ end_line: nil,
446
+ dir: +1)
447
+ if file_lines = frame.file_lines
448
+ frame_line = frame.location.lineno - 1
449
+
450
+ lines = file_lines.map.with_index do |e, i|
451
+ cur = i == frame_line ? '=>' : ' '
452
+ line = colorize_dim('%4d|' % (i+1))
453
+ "#{cur}#{line} #{e}"
454
+ end
431
455
 
432
- unless start_line
433
- if frame.show_line
434
- if dir > 0
435
- start_line = frame.show_line
436
- else
437
- end_line = frame.show_line - max_lines
438
- start_line = [end_line - max_lines, 0].max
439
- end
456
+ unless start_line
457
+ if frame.show_line
458
+ if dir > 0
459
+ start_line = frame.show_line
440
460
  else
441
- start_line = [frame_line - max_lines/2, 0].max
461
+ end_line = frame.show_line - max_lines
462
+ start_line = [end_line - max_lines, 0].max
442
463
  end
464
+ else
465
+ start_line = [frame_line - max_lines/2, 0].max
443
466
  end
467
+ end
444
468
 
445
- unless end_line
446
- end_line = [start_line + max_lines, lines.size].min
447
- end
469
+ unless end_line
470
+ end_line = [start_line + max_lines, lines.size].min
471
+ end
448
472
 
473
+ if start_line != end_line && max_lines
474
+ [start_line, end_line, lines]
475
+ end
476
+ else # no file lines
477
+ nil
478
+ end
479
+ rescue Exception => e
480
+ p e
481
+ pp e.backtrace
482
+ exit!
483
+ end
484
+
485
+ def show_src(frame_index: @current_frame_index, update_line: false, max_lines: CONFIG[:show_src_lines], **options)
486
+ if frame = get_frame(frame_index)
487
+ start_line, end_line, lines = *get_src(frame, max_lines: max_lines, **options)
488
+
489
+ if start_line
449
490
  if update_line
450
491
  frame.show_line = end_line
451
492
  end
452
493
 
453
- if start_line != end_line && max_lines
454
- puts "[#{start_line+1}, #{end_line}] in #{frame.pretty_path}" if !update_line && max_lines != 1
455
- puts lines[start_line ... end_line]
456
- end
457
- else # no file lines
494
+ puts "[#{start_line+1}, #{end_line}] in #{frame.pretty_path}" if !update_line && max_lines != 1
495
+ puts lines[start_line...end_line]
496
+ else
458
497
  puts "# No sourcefile available for #{frame.path}"
459
498
  end
460
499
  end
461
- rescue Exception => e
462
- p e
463
- pp e.backtrace
464
- exit!
465
500
  end
466
501
 
467
502
  def current_frame
@@ -513,8 +548,8 @@ module DEBUGGER__
513
548
 
514
549
  def show_ivars pat
515
550
  if s = current_frame&.self
516
- s.instance_variables.sort.each{|iv|
517
- value = s.instance_variable_get(iv)
551
+ M_INSTANCE_VARIABLES.bind_call(s).sort.each{|iv|
552
+ value = M_INSTANCE_VARIABLE_GET.bind_call(s, iv)
518
553
  puts_variable_info iv, value, pat
519
554
  }
520
555
  end
@@ -523,10 +558,10 @@ module DEBUGGER__
523
558
  def show_consts pat, only_self: false
524
559
  if s = current_frame&.self
525
560
  cs = {}
526
- if s.kind_of? Module
561
+ if M_KIND_OF_P.bind_call(s, Module)
527
562
  cs[s] = :self
528
563
  else
529
- s = s.class
564
+ s = M_CLASS.bind_call(s)
530
565
  cs[s] = :self unless only_self
531
566
  end
532
567
 
@@ -564,7 +599,7 @@ module DEBUGGER__
564
599
  return if pat && pat !~ label
565
600
 
566
601
  begin
567
- inspected = obj.inspect
602
+ inspected = DEBUGGER__.safe_inspect(obj)
568
603
  rescue Exception => e
569
604
  inspected = e.inspect
570
605
  end
@@ -623,15 +658,11 @@ module DEBUGGER__
623
658
  if @target_frames && (max ||= @target_frames.size) > 0
624
659
  frames = []
625
660
  @target_frames.each_with_index{|f, i|
626
- next if pattern && !(f.name.match?(pattern) || f.location_str.match?(pattern))
627
- next if CONFIG[:skip_path] && CONFIG[:skip_path].any?{|pat|
628
- case pat
629
- when String
630
- f.location_str.start_with?(pat)
631
- when Regexp
632
- f.location_str.match?(pat)
633
- end
634
- }
661
+ # we need to use FrameInfo#matchable_location because #location_str is for display
662
+ # and it may change based on configs (e.g. use_short_path)
663
+ next if pattern && !(f.name.match?(pattern) || f.matchable_location.match?(pattern))
664
+ # avoid using skip_path? because we still want to display internal frames
665
+ next if skip_config_skip_path?(f.matchable_location)
635
666
 
636
667
  frames << [i, f]
637
668
  }
@@ -668,18 +699,25 @@ module DEBUGGER__
668
699
  o = Output.new(@output)
669
700
 
670
701
  locals = current_frame&.local_variables
671
- klass = (obj.class == Class || obj.class == Module ? obj : obj.class)
672
702
 
673
- o.dump("constants", obj.constants) if obj.respond_to?(:constants)
703
+ klass = M_CLASS.bind_call(obj)
704
+ klass = obj if Class == klass || Module == klass
705
+
706
+ o.dump("constants", obj.constants) if M_RESPOND_TO_P.bind_call(obj, :constants)
674
707
  outline_method(o, klass, obj)
675
- o.dump("instance variables", obj.instance_variables)
708
+ o.dump("instance variables", M_INSTANCE_VARIABLES.bind_call(obj))
676
709
  o.dump("class variables", klass.class_variables)
677
710
  o.dump("locals", locals.keys) if locals
678
711
  end
679
712
  end
680
713
 
681
714
  def outline_method(o, klass, obj)
682
- singleton_class = begin obj.singleton_class; rescue TypeError; nil end
715
+ begin
716
+ singleton_class = M_SINGLETON_CLASS.bind_call(obj)
717
+ rescue TypeError
718
+ singleton_class = nil
719
+ end
720
+
683
721
  maps = class_method_map((singleton_class || klass).ancestors)
684
722
  maps.each do |mod, methods|
685
723
  name = mod == singleton_class ? "#{klass}.methods" : "#{mod}#methods"
@@ -699,6 +737,23 @@ module DEBUGGER__
699
737
 
700
738
  ## cmd: breakpoint
701
739
 
740
+ # TODO: support non-ASCII Constant name
741
+ def constant_name? name
742
+ case name
743
+ when /\A::\b/
744
+ constant_name? $~.post_match
745
+ when /\A[A-Z]\w*/
746
+ post = $~.post_match
747
+ if post.empty?
748
+ true
749
+ else
750
+ constant_name? post
751
+ end
752
+ else
753
+ false
754
+ end
755
+ end
756
+
702
757
  def make_breakpoint args
703
758
  case args.first
704
759
  when :method
@@ -706,9 +761,24 @@ module DEBUGGER__
706
761
  bp = MethodBreakpoint.new(current_frame.eval_binding, klass_name, op, method_name, cond: cond, command: cmd, path: path)
707
762
  begin
708
763
  bp.enable
764
+ rescue NameError => e
765
+ if bp.klass
766
+ puts "Unknown method name: \"#{e.name}\""
767
+ else
768
+ # klass_name can not be evaluated
769
+ if constant_name? klass_name
770
+ puts "Unknown constant name: \"#{e.name}\""
771
+ else
772
+ # only Class name is allowed
773
+ puts "Not a constant name: \"#{klass_name}\""
774
+ bp = nil
775
+ end
776
+ end
777
+
778
+ Session.activate_method_added_trackers if bp
709
779
  rescue Exception => e
710
- puts e.message
711
- ::DEBUGGER__::METHOD_ADDED_TRACKER.enable
780
+ puts e.inspect
781
+ bp = nil
712
782
  end
713
783
 
714
784
  bp
@@ -981,7 +1051,7 @@ module DEBUGGER__
981
1051
  begin
982
1052
  obj = frame_eval args.shift, re_raise: true
983
1053
  opt = args.shift
984
- obj_inspect = obj.inspect
1054
+ obj_inspect = DEBUGGER__.safe_inspect(obj)
985
1055
 
986
1056
  width = 50
987
1057
 
@@ -989,7 +1059,7 @@ module DEBUGGER__
989
1059
  obj_inspect = truncate(obj_inspect, width: width)
990
1060
  end
991
1061
 
992
- event! :result, :trace_pass, obj.object_id, obj_inspect, opt
1062
+ event! :result, :trace_pass, M_OBJECT_ID.bind_call(obj), obj_inspect, opt
993
1063
  rescue => e
994
1064
  puts e.message
995
1065
  event! :result, nil
@@ -1006,8 +1076,8 @@ module DEBUGGER__
1006
1076
  # enable recording
1007
1077
  if !@recorder
1008
1078
  @recorder = Recorder.new
1009
- @recorder.enable
1010
1079
  end
1080
+ @recorder.enable
1011
1081
  when :off
1012
1082
  if @recorder&.enabled?
1013
1083
  @recorder.disable
@@ -1039,6 +1109,33 @@ module DEBUGGER__
1039
1109
  raise
1040
1110
  end
1041
1111
 
1112
+ def debug_event(ev, args)
1113
+ DEBUGGER__.debug{
1114
+ args = args.map { |arg| DEBUGGER__.safe_inspect(arg) }
1115
+ "#{inspect} sends Event { type: #{ev.inspect}, args: #{args} } to Session"
1116
+ }
1117
+ end
1118
+
1119
+ def debug_mode(old_mode, new_mode)
1120
+ DEBUGGER__.debug{
1121
+ "#{inspect} changes mode (#{old_mode} -> #{new_mode})"
1122
+ }
1123
+ end
1124
+
1125
+ def debug_cmd(cmds)
1126
+ DEBUGGER__.debug{
1127
+ cmd, *args = *cmds
1128
+ args = args.map { |arg| DEBUGGER__.safe_inspect(arg) }
1129
+ "#{inspect} receives Cmd { type: #{cmd.inspect}, args: #{args} } from Session"
1130
+ }
1131
+ end
1132
+
1133
+ def debug_suspend(event)
1134
+ DEBUGGER__.debug{
1135
+ "#{inspect} is suspended for #{event.inspect}"
1136
+ }
1137
+ end
1138
+
1042
1139
  class Recorder
1043
1140
  attr_reader :log, :index
1044
1141
  attr_accessor :backup_frames
data/lib/debug/tracer.rb CHANGED
@@ -74,7 +74,7 @@ module DEBUGGER__
74
74
  end
75
75
 
76
76
  def out tp, msg = nil, depth = caller.size - 1
77
- location_str = colorize("#{tp.path}:#{tp.lineno}", [:GREEN])
77
+ location_str = colorize("#{FrameInfo.pretty_path(tp.path)}:#{tp.lineno}", [:GREEN])
78
78
  buff = "#{header(depth)}#{msg} at #{location_str}"
79
79
 
80
80
  if false # TODO: Ractor.main?
@@ -119,7 +119,6 @@ module DEBUGGER__
119
119
  next if skip?(tp)
120
120
 
121
121
  depth = caller.size
122
- sp = ' ' * depth
123
122
 
124
123
  call_identifier_str =
125
124
  if tp.defined_class
@@ -133,9 +132,11 @@ module DEBUGGER__
133
132
  case tp.event
134
133
  when :call, :c_call, :b_call
135
134
  depth += 1 if tp.event == :c_call
135
+ sp = ' ' * depth
136
136
  out tp, ">#{sp}#{call_identifier_str}", depth
137
137
  when :return, :c_return, :b_return
138
138
  depth += 1 if tp.event == :c_return
139
+ sp = ' ' * depth
139
140
  return_str = colorize_magenta(DEBUGGER__.safe_inspect(tp.return_value, short: true))
140
141
  out tp, "<#{sp}#{call_identifier_str} #=> #{return_str}", depth
141
142
  end
@@ -185,7 +186,7 @@ module DEBUGGER__
185
186
  @tracer = TracePoint.new(:a_call){|tp|
186
187
  next if skip?(tp)
187
188
 
188
- if tp.self.object_id == @obj_id
189
+ if M_OBJECT_ID.bind_call(tp.self) == @obj_id
189
190
  klass = tp.defined_class
190
191
  method = tp.method_id
191
192
  method_info =
data/lib/debug/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DEBUGGER__
4
- VERSION = "1.5.0"
4
+ VERSION = "1.6.0"
5
5
  end
data/misc/README.md.erb CHANGED
@@ -9,11 +9,15 @@ New debug.rb has several advantages:
9
9
 
10
10
  * Fast: No performance penalty on non-stepping mode and non-breakpoints.
11
11
  * [Remote debugging](#remote-debugging): Support remote debugging natively.
12
- * UNIX domain socket
12
+ * UNIX domain socket (UDS)
13
13
  * TCP/IP
14
- * Integration with rich debugger frontend
15
- * VSCode/DAP ([VSCode rdbg Ruby Debugger - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=KoichiSasada.vscode-rdbg))
16
- * Chrome DevTools
14
+ * Integration with rich debugger frontends
15
+
16
+ Frontend | [Console](https://github.com/ruby/debug#invoke-as-a-remote-debuggee) | [VSCode](https://github.com/ruby/debug#vscode-integration) | [Chrome DevTool](#chrome-devtool-integration) |
17
+ ---|---|---|---|
18
+ Connection | UDS, TCP/IP | UDS, TCP/IP | TCP/IP |
19
+ Requirement | No | [vscode-rdbg](https://marketplace.visualstudio.com/items?itemName=KoichiSasada.vscode-rdbg) | Chrome |
20
+
17
21
  * Extensible: application can introduce debugging support with several ways:
18
22
  * By `rdbg` command
19
23
  * By loading libraries with `-r` command line option
@@ -38,6 +42,9 @@ If you use Bundler, write the following line to your Gemfile.
38
42
  gem "debug", ">= 1.0.0"
39
43
  ```
40
44
 
45
+ (The version constraint is important; `debug < 1.0.0` is an older,
46
+ abandoned gem that is completely different from this product.)
47
+
41
48
  # HOW TO USE
42
49
 
43
50
  To use a debugger, roughly you will do the following steps:
@@ -134,7 +141,7 @@ d => 4
134
141
  ### Invoke the program from the debugger as a traditional debuggers
135
142
 
136
143
  If you don't want to modify the source code, you can set breakpoints with a debug command `break` (`b` for short).
137
- Using `rdbg` command to launch the program without any modifications, you can run the program with the debugger.
144
+ Using `rdbg` command (or `bundle exec rdbg`) to launch the program without any modifications, you can run the program with the debugger.
138
145
 
139
146
  ```shell
140
147
  $ cat target.rb # Sample program
@@ -280,7 +287,12 @@ You can run your application as a remote debuggee and the remote debugger consol
280
287
 
281
288
  ### Invoke as a remote debuggee
282
289
 
283
- There are two ways to invoke a script as remote debuggee: Use `rdbg --open` and require `debug/open` (or `debug/open_nonstop`).
290
+ There are multiple ways to run your program as a debuggee:
291
+
292
+ Stop at program start | [`rdbg` option](https://github.com/ruby/debug#rdbg---open-or-rdbg--o-for-short) | [require](https://github.com/ruby/debug#require-debugopen-in-a-program) | [debugger API](https://github.com/ruby/debug#start-by-method)
293
+ ---|---|---|---|
294
+ Yes | `rdbg --open` | `require "debug/open"` | `DEBUGGER__.open`
295
+ No | `rdbg --open --nonstop` | `require "debug/open_nonstop"` | `DEBUGGER__.open(nonstop: true)`
284
296
 
285
297
  #### `rdbg --open` (or `rdbg -O` for short)
286
298
 
@@ -452,10 +464,18 @@ config set log_level INFO
452
464
  config set no_color true
453
465
  ```
454
466
 
455
- <% cat = nil; DEBUGGER__::CONFIG_SET.each do |key, (env, desc)| %>
467
+ <% cat = nil; DEBUGGER__::CONFIG_SET.each do |key, (env, desc, _, default)| %>
456
468
  <% /\A(\w+): (.+)/ =~ desc; if cat != $1; cat = 1 %>
457
469
  * <%= $1 %>
458
- <% cat = $1; end %> * `<%= env %>` (`<%= key %>`): <%= $2 %><% end %>
470
+ <% cat = $1; end %> * `<%= env %>` (`<%= key %>`): <%= default ? "#{$2} (default: #{default})" : $2 %><% end %>
471
+
472
+ There are other environment variables:
473
+
474
+ * `NO_COLOR`: If the value is set, set `RUBY_DEBUG_NO_COLOR` ([NO_COLOR: disabling ANSI color output in various Unix commands](https://no-color.org/)).
475
+ * `RUBY_DEBUG_ENABLE`: If the value is `0`, do not enable debug.gem feature.
476
+ * `RUBY_DEBUG_ADDED_RUBYOPT`: Remove this value from `RUBYOPT` at first. This feature helps loading debug.gem with `RUBYOPT='-r debug/...'` and you don't want to derive it to child processes. In this case you can set `RUBY_DEBUG_ADDED_RUBYOPT='-r debug/...'` (same value) and this string will be deleted from `RUBYOPT` at first.
477
+ * `RUBY_DEBUG_EDITOR` or `EDITOR`: An editor used by `edit` debug command.
478
+ * `RUBY_DEBUG_BB`: Define `Kernel#bb` method which is alias of `Kernel#debugger`.
459
479
 
460
480
  ### Initial scripts
461
481
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: debug
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koichi Sasada
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-30 00:00:00.000000000 Z
11
+ date: 2022-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: irb
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.2.7
33
+ version: 0.3.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 0.2.7
40
+ version: 0.3.1
41
41
  description: Debugging functionality for Ruby. This is completely rewritten debug.rb
42
42
  which was contained by the ancient Ruby versions.
43
43
  email:
@@ -60,7 +60,6 @@ files:
60
60
  - ext/debug/extconf.rb
61
61
  - ext/debug/iseq_collector.c
62
62
  - lib/debug.rb
63
- - lib/debug/bp.vim
64
63
  - lib/debug/breakpoint.rb
65
64
  - lib/debug/client.rb
66
65
  - lib/debug/color.rb
@@ -103,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
102
  - !ruby/object:Gem::Version
104
103
  version: '0'
105
104
  requirements: []
106
- rubygems_version: 3.4.0.dev
105
+ rubygems_version: 3.3.7
107
106
  signing_key:
108
107
  specification_version: 4
109
108
  summary: Debugging functionality for Ruby
data/lib/debug/bp.vim DELETED
@@ -1,68 +0,0 @@
1
- let g:rdb_bps = {}
2
-
3
- function SET_BP()
4
- let signed = sign_getplaced(bufname(), {'lnum': line('.')})
5
- if empty(signed[0]['signs'])
6
- call sign_place(0, '', 'signBP', bufname(), {'lnum': line('.')})
7
- else
8
- "echo signed[0]['signs']
9
- call sign_unplace('', {'buffer': bufname(), 'id': signed[0]['signs'][0]['id']})
10
- endif
11
- endfunction
12
-
13
- function UPDATE_BPS()
14
- let signs = sign_getplaced(bufname())
15
- let key = expand('%:p')
16
-
17
- if empty(signs[0]['signs'])
18
- let removed = remove(g:rdb_bps, key)
19
- else
20
- let g:rdb_bps[key] = signs[0]['signs']
21
- endif
22
- endfunction
23
-
24
- function APPLY_BPS()
25
- let key = expand('%:p')
26
- if has_key(g:rdb_bps, key)
27
- for b in g:rdb_bps[key]
28
- call sign_place(0, '', 'signBP', bufname(), {'lnum': b['lnum']})
29
- endfor
30
- endif
31
- endfunction
32
-
33
- function WRITE_BPS()
34
- call writefile([json_encode(g:rdb_bps)], '.rdb_breakpoints.json')
35
- endfunction
36
-
37
- " load
38
- try
39
- let json = readfile('.rdb_breakpoints.json')
40
- let g:rdb_bps = json_decode(json[0])
41
- " {"/full/path/to/file1": [{"lnum": 10}, ...], ...}
42
- catch /Can't open/
43
- let g:rdb_bps = {}
44
- catch /Invalid arguments for function json_decode/
45
- let g:rdb_bps = {}
46
- endtry
47
-
48
- sign define signBP text=BR
49
-
50
- call APPLY_BPS()
51
-
52
- autocmd BufReadPost * call APPLY_BPS()
53
- autocmd BufUnload * call UPDATE_BPS()
54
- autocmd VimLeave * call WRITE_BPS()
55
-
56
- function! s:ruby_bp_settings() abort
57
- echomsg "Type <Space> to toggle break points and <q> to quit"
58
-
59
- if &readonly
60
- nnoremap <silent> <buffer> <Space> :call SET_BP()<CR>
61
- nnoremap <silent> <buffer> q :<C-u>quit<CR>
62
- endif
63
- endfunction
64
-
65
- " autocmd FileType ruby call s:ruby_bp_settings()
66
- autocmd BufEnter *.rb call s:ruby_bp_settings()
67
-
68
- call s:ruby_bp_settings()