irb 1.7.1 → 1.13.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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/.document +1 -1
  3. data/Gemfile +10 -1
  4. data/README.md +265 -20
  5. data/Rakefile +13 -10
  6. data/doc/irb/irb.rd.ja +1 -3
  7. data/irb.gemspec +2 -1
  8. data/lib/irb/cmd/nop.rb +3 -52
  9. data/lib/irb/color.rb +4 -2
  10. data/lib/irb/command/backtrace.rb +17 -0
  11. data/lib/irb/command/base.rb +62 -0
  12. data/lib/irb/command/break.rb +17 -0
  13. data/lib/irb/command/catch.rb +17 -0
  14. data/lib/irb/command/chws.rb +40 -0
  15. data/lib/irb/command/context.rb +16 -0
  16. data/lib/irb/{cmd → command}/continue.rb +3 -3
  17. data/lib/irb/command/debug.rb +71 -0
  18. data/lib/irb/{cmd → command}/delete.rb +3 -3
  19. data/lib/irb/command/disable_irb.rb +19 -0
  20. data/lib/irb/command/edit.rb +63 -0
  21. data/lib/irb/command/exit.rb +18 -0
  22. data/lib/irb/{cmd → command}/finish.rb +3 -3
  23. data/lib/irb/command/force_exit.rb +18 -0
  24. data/lib/irb/command/help.rb +83 -0
  25. data/lib/irb/command/history.rb +45 -0
  26. data/lib/irb/command/info.rb +17 -0
  27. data/lib/irb/command/internal_helpers.rb +27 -0
  28. data/lib/irb/{cmd → command}/irb_info.rb +7 -7
  29. data/lib/irb/{cmd → command}/load.rb +23 -8
  30. data/lib/irb/{cmd → command}/ls.rb +42 -19
  31. data/lib/irb/{cmd → command}/measure.rb +18 -17
  32. data/lib/irb/{cmd → command}/next.rb +3 -3
  33. data/lib/irb/command/pushws.rb +65 -0
  34. data/lib/irb/command/show_doc.rb +51 -0
  35. data/lib/irb/command/show_source.rb +74 -0
  36. data/lib/irb/{cmd → command}/step.rb +3 -3
  37. data/lib/irb/command/subirb.rb +123 -0
  38. data/lib/irb/{cmd → command}/whereami.rb +3 -5
  39. data/lib/irb/command.rb +23 -0
  40. data/lib/irb/completion.rb +133 -102
  41. data/lib/irb/context.rb +182 -66
  42. data/lib/irb/debug/ui.rb +103 -0
  43. data/lib/irb/{cmd/debug.rb → debug.rb} +53 -59
  44. data/lib/irb/default_commands.rb +265 -0
  45. data/lib/irb/easter-egg.rb +16 -6
  46. data/lib/irb/ext/change-ws.rb +6 -8
  47. data/lib/irb/ext/{history.rb → eval_history.rb} +7 -7
  48. data/lib/irb/ext/loader.rb +4 -4
  49. data/lib/irb/ext/multi-irb.rb +5 -5
  50. data/lib/irb/ext/tracer.rb +12 -51
  51. data/lib/irb/ext/use-loader.rb +6 -8
  52. data/lib/irb/ext/workspaces.rb +10 -34
  53. data/lib/irb/frame.rb +1 -1
  54. data/lib/irb/help.rb +3 -3
  55. data/lib/irb/helper_method/base.rb +16 -0
  56. data/lib/irb/helper_method/conf.rb +11 -0
  57. data/lib/irb/helper_method.rb +29 -0
  58. data/lib/irb/{ext/save-history.rb → history.rb} +20 -58
  59. data/lib/irb/init.rb +154 -58
  60. data/lib/irb/input-method.rb +238 -203
  61. data/lib/irb/inspector.rb +3 -3
  62. data/lib/irb/lc/error.rb +1 -11
  63. data/lib/irb/lc/help-message +4 -0
  64. data/lib/irb/lc/ja/error.rb +1 -11
  65. data/lib/irb/lc/ja/help-message +13 -0
  66. data/lib/irb/locale.rb +2 -2
  67. data/lib/irb/nesting_parser.rb +13 -3
  68. data/lib/irb/notifier.rb +1 -1
  69. data/lib/irb/output-method.rb +2 -8
  70. data/lib/irb/pager.rb +91 -0
  71. data/lib/irb/ruby-lex.rb +391 -471
  72. data/lib/irb/ruby_logo.aa +43 -0
  73. data/lib/irb/source_finder.rb +139 -0
  74. data/lib/irb/statement.rb +80 -0
  75. data/lib/irb/version.rb +3 -3
  76. data/lib/irb/workspace.rb +24 -4
  77. data/lib/irb/ws-for-case-2.rb +1 -1
  78. data/lib/irb/xmp.rb +3 -3
  79. data/lib/irb.rb +1232 -604
  80. data/man/irb.1 +7 -0
  81. metadata +60 -32
  82. data/lib/irb/cmd/backtrace.rb +0 -21
  83. data/lib/irb/cmd/break.rb +0 -21
  84. data/lib/irb/cmd/catch.rb +0 -21
  85. data/lib/irb/cmd/chws.rb +0 -36
  86. data/lib/irb/cmd/edit.rb +0 -61
  87. data/lib/irb/cmd/help.rb +0 -23
  88. data/lib/irb/cmd/info.rb +0 -21
  89. data/lib/irb/cmd/pushws.rb +0 -45
  90. data/lib/irb/cmd/show_cmds.rb +0 -39
  91. data/lib/irb/cmd/show_doc.rb +0 -48
  92. data/lib/irb/cmd/show_source.rb +0 -113
  93. data/lib/irb/cmd/subirb.rb +0 -66
  94. data/lib/irb/extend-command.rb +0 -356
  95. data/lib/irb/src_encoding.rb +0 -7
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/completion.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ishitsuka.com)
@@ -8,30 +8,7 @@
8
8
  require_relative 'ruby-lex'
9
9
 
10
10
  module IRB
11
- module InputCompletor # :nodoc:
12
- using Module.new {
13
- refine ::Binding do
14
- def eval_methods
15
- ::Kernel.instance_method(:methods).bind(eval("self")).call
16
- end
17
-
18
- def eval_private_methods
19
- ::Kernel.instance_method(:private_methods).bind(eval("self")).call
20
- end
21
-
22
- def eval_instance_variables
23
- ::Kernel.instance_method(:instance_variables).bind(eval("self")).call
24
- end
25
-
26
- def eval_global_variables
27
- ::Kernel.instance_method(:global_variables).bind(eval("self")).call
28
- end
29
-
30
- def eval_class_constants
31
- ::Module.instance_method(:constants).bind(eval("self.class")).call
32
- end
33
- end
34
- }
11
+ class BaseCompletor # :nodoc:
35
12
 
36
13
  # Set of reserved words used by Ruby, you should not use these for
37
14
  # constants or variables
@@ -56,7 +33,13 @@ module IRB
56
33
  yield
57
34
  ]
58
35
 
59
- BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
36
+ def completion_candidates(preposing, target, postposing, bind:)
37
+ raise NotImplementedError
38
+ end
39
+
40
+ def doc_namespace(preposing, matched, postposing, bind:)
41
+ raise NotImplementedError
42
+ end
60
43
 
61
44
  GEM_PATHS =
62
45
  if defined?(Gem::Specification)
@@ -73,7 +56,7 @@ module IRB
73
56
  []
74
57
  end.freeze
75
58
 
76
- def self.retrieve_gem_and_system_load_path
59
+ def retrieve_gem_and_system_load_path
77
60
  candidates = (GEM_PATHS | $LOAD_PATH)
78
61
  candidates.map do |p|
79
62
  if p.respond_to?(:to_path)
@@ -84,8 +67,8 @@ module IRB
84
67
  end.compact.sort
85
68
  end
86
69
 
87
- def self.retrieve_files_to_require_from_load_path
88
- @@files_from_load_path ||=
70
+ def retrieve_files_to_require_from_load_path
71
+ @files_from_load_path ||=
89
72
  (
90
73
  shortest = []
91
74
  rest = retrieve_gem_and_system_load_path.each_with_object([]) { |path, result|
@@ -103,13 +86,74 @@ module IRB
103
86
  )
104
87
  end
105
88
 
106
- def self.retrieve_files_to_require_relative_from_current_dir
107
- @@files_from_current_dir ||= Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: '.').map { |path|
89
+ def command_completions(preposing, target)
90
+ if preposing.empty? && !target.empty?
91
+ IRB::Command.command_names.select { _1.start_with?(target) }
92
+ else
93
+ []
94
+ end
95
+ end
96
+
97
+ def retrieve_files_to_require_relative_from_current_dir
98
+ @files_from_current_dir ||= Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: '.').map { |path|
108
99
  path.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '')
109
100
  }
110
101
  end
102
+ end
103
+
104
+ class TypeCompletor < BaseCompletor # :nodoc:
105
+ def initialize(context)
106
+ @context = context
107
+ end
108
+
109
+ def inspect
110
+ ReplTypeCompletor.info
111
+ end
112
+
113
+ def completion_candidates(preposing, target, _postposing, bind:)
114
+ commands = command_completions(preposing, target)
115
+ result = ReplTypeCompletor.analyze(preposing + target, binding: bind, filename: @context.irb_path)
116
+ return commands unless result
117
+
118
+ commands | result.completion_candidates.map { target + _1 }
119
+ end
120
+
121
+ def doc_namespace(preposing, matched, _postposing, bind:)
122
+ result = ReplTypeCompletor.analyze(preposing + matched, binding: bind, filename: @context.irb_path)
123
+ result&.doc_namespace('')
124
+ end
125
+ end
126
+
127
+ class RegexpCompletor < BaseCompletor # :nodoc:
128
+ using Module.new {
129
+ refine ::Binding do
130
+ def eval_methods
131
+ ::Kernel.instance_method(:methods).bind(eval("self")).call
132
+ end
133
+
134
+ def eval_private_methods
135
+ ::Kernel.instance_method(:private_methods).bind(eval("self")).call
136
+ end
137
+
138
+ def eval_instance_variables
139
+ ::Kernel.instance_method(:instance_variables).bind(eval("self")).call
140
+ end
141
+
142
+ def eval_global_variables
143
+ ::Kernel.instance_method(:global_variables).bind(eval("self")).call
144
+ end
145
+
146
+ def eval_class_constants
147
+ ::Module.instance_method(:constants).bind(eval("self.class")).call
148
+ end
149
+ end
150
+ }
151
+
152
+ def inspect
153
+ 'RegexpCompletor'
154
+ end
111
155
 
112
- CompletionRequireProc = lambda { |target, preposing = nil, postposing = nil|
156
+ def complete_require_path(target, preposing, postposing)
113
157
  if target =~ /\A(['"])([^'"]+)\Z/
114
158
  quote = $1
115
159
  actual_target = $2
@@ -124,39 +168,38 @@ module IRB
124
168
  break
125
169
  end
126
170
  end
127
- result = []
128
- if tok && tok.event == :on_ident && tok.state == Ripper::EXPR_CMDARG
129
- case tok.tok
130
- when 'require'
131
- result = retrieve_files_to_require_from_load_path.select { |path|
132
- path.start_with?(actual_target)
133
- }.map { |path|
134
- quote + path
135
- }
136
- when 'require_relative'
137
- result = retrieve_files_to_require_relative_from_current_dir.select { |path|
138
- path.start_with?(actual_target)
139
- }.map { |path|
140
- quote + path
141
- }
142
- end
171
+ return unless tok&.event == :on_ident && tok.state == Ripper::EXPR_CMDARG
172
+
173
+ case tok.tok
174
+ when 'require'
175
+ retrieve_files_to_require_from_load_path.select { |path|
176
+ path.start_with?(actual_target)
177
+ }.map { |path|
178
+ quote + path
179
+ }
180
+ when 'require_relative'
181
+ retrieve_files_to_require_relative_from_current_dir.select { |path|
182
+ path.start_with?(actual_target)
183
+ }.map { |path|
184
+ quote + path
185
+ }
143
186
  end
144
- result
145
- }
187
+ end
146
188
 
147
- CompletionProc = lambda { |target, preposing = nil, postposing = nil|
189
+ def completion_candidates(preposing, target, postposing, bind:)
148
190
  if preposing && postposing
149
- result = CompletionRequireProc.(target, preposing, postposing)
150
- unless result
151
- result = retrieve_completion_data(target).compact.map{ |i| i.encode(Encoding.default_external) }
152
- end
153
- result
154
- else
155
- retrieve_completion_data(target).compact.map{ |i| i.encode(Encoding.default_external) }
191
+ result = complete_require_path(target, preposing, postposing)
192
+ return result if result
156
193
  end
157
- }
194
+ commands = command_completions(preposing || '', target)
195
+ commands | retrieve_completion_data(target, bind: bind, doc_namespace: false).compact.map{ |i| i.encode(Encoding.default_external) }
196
+ end
197
+
198
+ def doc_namespace(_preposing, matched, _postposing, bind:)
199
+ retrieve_completion_data(matched, bind: bind, doc_namespace: true)
200
+ end
158
201
 
159
- def self.retrieve_completion_data(input, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding, doc_namespace: false)
202
+ def retrieve_completion_data(input, bind:, doc_namespace:)
160
203
  case input
161
204
  # this regexp only matches the closing character because of irb's Reline.completer_quote_characters setting
162
205
  # details are described in: https://github.com/ruby/irb/pull/523
@@ -199,16 +242,16 @@ module IRB
199
242
  end
200
243
 
201
244
  when /^([^\}]*\})\.([^.]*)$/
202
- # Proc or Hash
245
+ # Hash or Proc
203
246
  receiver = $1
204
247
  message = $2
205
248
 
206
249
  if doc_namespace
207
- ["Proc.#{message}", "Hash.#{message}"]
250
+ ["Hash.#{message}", "Proc.#{message}"]
208
251
  else
209
- proc_candidates = Proc.instance_methods.collect{|m| m.to_s}
210
252
  hash_candidates = Hash.instance_methods.collect{|m| m.to_s}
211
- select_message(receiver, message, proc_candidates | hash_candidates)
253
+ proc_candidates = Proc.instance_methods.collect{|m| m.to_s}
254
+ select_message(receiver, message, hash_candidates | proc_candidates)
212
255
  end
213
256
 
214
257
  when /^(:[^:.]+)$/
@@ -356,7 +399,7 @@ module IRB
356
399
 
357
400
  if doc_namespace
358
401
  rec_class = rec.is_a?(Module) ? rec : rec.class
359
- "#{rec_class.name}#{sep}#{candidates.find{ |i| i == message }}"
402
+ "#{rec_class.name}#{sep}#{candidates.find{ |i| i == message }}" rescue nil
360
403
  else
361
404
  select_message(receiver, message, candidates, sep)
362
405
  end
@@ -374,13 +417,19 @@ module IRB
374
417
  else
375
418
  select_message(receiver, message, candidates.sort)
376
419
  end
377
-
420
+ when /^\s*$/
421
+ # empty input
422
+ if doc_namespace
423
+ nil
424
+ else
425
+ []
426
+ end
378
427
  else
379
428
  if doc_namespace
380
429
  vars = (bind.local_variables | bind.eval_instance_variables).collect{|m| m.to_s}
381
430
  perfect_match_var = vars.find{|m| m.to_s == input}
382
431
  if perfect_match_var
383
- eval("#{perfect_match_var}.class.name", bind)
432
+ eval("#{perfect_match_var}.class.name", bind) rescue nil
384
433
  else
385
434
  candidates = (bind.eval_methods | bind.eval_private_methods | bind.local_variables | bind.eval_instance_variables | bind.eval_class_constants).collect{|m| m.to_s}
386
435
  candidates |= ReservedWords
@@ -394,44 +443,10 @@ module IRB
394
443
  end
395
444
  end
396
445
 
397
- PerfectMatchedProc = ->(matched, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding) {
398
- begin
399
- require 'rdoc'
400
- rescue LoadError
401
- return
402
- end
403
-
404
- RDocRIDriver ||= RDoc::RI::Driver.new
405
-
406
- if matched =~ /\A(?:::)?RubyVM/ and not ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
407
- IRB.__send__(:easter_egg)
408
- return
409
- end
410
-
411
- namespace = retrieve_completion_data(matched, bind: bind, doc_namespace: true)
412
- return unless namespace
413
-
414
- if namespace.is_a?(Array)
415
- out = RDoc::Markup::Document.new
416
- namespace.each do |m|
417
- begin
418
- RDocRIDriver.add_method(out, m)
419
- rescue RDoc::RI::Driver::NotFoundError
420
- end
421
- end
422
- RDocRIDriver.display(out)
423
- else
424
- begin
425
- RDocRIDriver.display_names([namespace])
426
- rescue RDoc::RI::Driver::NotFoundError
427
- end
428
- end
429
- }
430
-
431
446
  # Set of available operators in Ruby
432
447
  Operators = %w[% & * ** + - / < << <= <=> == === =~ > >= >> [] []= ^ ! != !~]
433
448
 
434
- def self.select_message(receiver, message, candidates, sep = ".")
449
+ def select_message(receiver, message, candidates, sep = ".")
435
450
  candidates.grep(/^#{Regexp.quote(message)}/).collect do |e|
436
451
  case e
437
452
  when /^[a-zA-Z_]/
@@ -443,4 +458,20 @@ module IRB
443
458
  end
444
459
  end
445
460
  end
461
+
462
+ module InputCompletor
463
+ class << self
464
+ private def regexp_completor
465
+ @regexp_completor ||= RegexpCompletor.new
466
+ end
467
+
468
+ def retrieve_completion_data(input, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding, doc_namespace: false)
469
+ regexp_completor.retrieve_completion_data(input, bind: bind, doc_namespace: doc_namespace)
470
+ end
471
+ end
472
+ CompletionProc = ->(target, preposing = nil, postposing = nil) {
473
+ regexp_completor.completion_candidates(preposing, target, postposing, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding)
474
+ }
475
+ end
476
+ deprecate_constant :InputCompletor
446
477
  end