debug 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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()