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.
- checksums.yaml +4 -4
- data/.document +1 -1
- data/Gemfile +10 -1
- data/README.md +265 -20
- data/Rakefile +13 -10
- data/doc/irb/irb.rd.ja +1 -3
- data/irb.gemspec +2 -1
- data/lib/irb/cmd/nop.rb +3 -52
- data/lib/irb/color.rb +4 -2
- data/lib/irb/command/backtrace.rb +17 -0
- data/lib/irb/command/base.rb +62 -0
- data/lib/irb/command/break.rb +17 -0
- data/lib/irb/command/catch.rb +17 -0
- data/lib/irb/command/chws.rb +40 -0
- data/lib/irb/command/context.rb +16 -0
- data/lib/irb/{cmd → command}/continue.rb +3 -3
- data/lib/irb/command/debug.rb +71 -0
- data/lib/irb/{cmd → command}/delete.rb +3 -3
- data/lib/irb/command/disable_irb.rb +19 -0
- data/lib/irb/command/edit.rb +63 -0
- data/lib/irb/command/exit.rb +18 -0
- data/lib/irb/{cmd → command}/finish.rb +3 -3
- data/lib/irb/command/force_exit.rb +18 -0
- data/lib/irb/command/help.rb +83 -0
- data/lib/irb/command/history.rb +45 -0
- data/lib/irb/command/info.rb +17 -0
- data/lib/irb/command/internal_helpers.rb +27 -0
- data/lib/irb/{cmd → command}/irb_info.rb +7 -7
- data/lib/irb/{cmd → command}/load.rb +23 -8
- data/lib/irb/{cmd → command}/ls.rb +42 -19
- data/lib/irb/{cmd → command}/measure.rb +18 -17
- data/lib/irb/{cmd → command}/next.rb +3 -3
- data/lib/irb/command/pushws.rb +65 -0
- data/lib/irb/command/show_doc.rb +51 -0
- data/lib/irb/command/show_source.rb +74 -0
- data/lib/irb/{cmd → command}/step.rb +3 -3
- data/lib/irb/command/subirb.rb +123 -0
- data/lib/irb/{cmd → command}/whereami.rb +3 -5
- data/lib/irb/command.rb +23 -0
- data/lib/irb/completion.rb +133 -102
- data/lib/irb/context.rb +182 -66
- data/lib/irb/debug/ui.rb +103 -0
- data/lib/irb/{cmd/debug.rb → debug.rb} +53 -59
- data/lib/irb/default_commands.rb +265 -0
- data/lib/irb/easter-egg.rb +16 -6
- data/lib/irb/ext/change-ws.rb +6 -8
- data/lib/irb/ext/{history.rb → eval_history.rb} +7 -7
- data/lib/irb/ext/loader.rb +4 -4
- data/lib/irb/ext/multi-irb.rb +5 -5
- data/lib/irb/ext/tracer.rb +12 -51
- data/lib/irb/ext/use-loader.rb +6 -8
- data/lib/irb/ext/workspaces.rb +10 -34
- data/lib/irb/frame.rb +1 -1
- data/lib/irb/help.rb +3 -3
- data/lib/irb/helper_method/base.rb +16 -0
- data/lib/irb/helper_method/conf.rb +11 -0
- data/lib/irb/helper_method.rb +29 -0
- data/lib/irb/{ext/save-history.rb → history.rb} +20 -58
- data/lib/irb/init.rb +154 -58
- data/lib/irb/input-method.rb +238 -203
- data/lib/irb/inspector.rb +3 -3
- data/lib/irb/lc/error.rb +1 -11
- data/lib/irb/lc/help-message +4 -0
- data/lib/irb/lc/ja/error.rb +1 -11
- data/lib/irb/lc/ja/help-message +13 -0
- data/lib/irb/locale.rb +2 -2
- data/lib/irb/nesting_parser.rb +13 -3
- data/lib/irb/notifier.rb +1 -1
- data/lib/irb/output-method.rb +2 -8
- data/lib/irb/pager.rb +91 -0
- data/lib/irb/ruby-lex.rb +391 -471
- data/lib/irb/ruby_logo.aa +43 -0
- data/lib/irb/source_finder.rb +139 -0
- data/lib/irb/statement.rb +80 -0
- data/lib/irb/version.rb +3 -3
- data/lib/irb/workspace.rb +24 -4
- data/lib/irb/ws-for-case-2.rb +1 -1
- data/lib/irb/xmp.rb +3 -3
- data/lib/irb.rb +1232 -604
- data/man/irb.1 +7 -0
- metadata +60 -32
- data/lib/irb/cmd/backtrace.rb +0 -21
- data/lib/irb/cmd/break.rb +0 -21
- data/lib/irb/cmd/catch.rb +0 -21
- data/lib/irb/cmd/chws.rb +0 -36
- data/lib/irb/cmd/edit.rb +0 -61
- data/lib/irb/cmd/help.rb +0 -23
- data/lib/irb/cmd/info.rb +0 -21
- data/lib/irb/cmd/pushws.rb +0 -45
- data/lib/irb/cmd/show_cmds.rb +0 -39
- data/lib/irb/cmd/show_doc.rb +0 -48
- data/lib/irb/cmd/show_source.rb +0 -113
- data/lib/irb/cmd/subirb.rb +0 -66
- data/lib/irb/extend-command.rb +0 -356
- data/lib/irb/src_encoding.rb +0 -7
data/lib/irb/completion.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# frozen_string_literal:
|
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
|
-
|
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
|
-
|
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
|
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
|
88
|
-
|
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
|
107
|
-
|
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
|
-
|
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
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
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
|
-
|
145
|
-
}
|
187
|
+
end
|
146
188
|
|
147
|
-
|
189
|
+
def completion_candidates(preposing, target, postposing, bind:)
|
148
190
|
if preposing && postposing
|
149
|
-
result =
|
150
|
-
|
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
|
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
|
-
#
|
245
|
+
# Hash or Proc
|
203
246
|
receiver = $1
|
204
247
|
message = $2
|
205
248
|
|
206
249
|
if doc_namespace
|
207
|
-
["
|
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
|
-
|
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
|
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
|