irb 1.6.3 → 1.7.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.
- checksums.yaml +4 -4
- data/README.md +3 -0
- data/irb.gemspec +1 -1
- data/lib/irb/cmd/help.rb +12 -46
- data/lib/irb/cmd/ls.rb +5 -2
- data/lib/irb/cmd/nop.rb +5 -14
- data/lib/irb/cmd/show_doc.rb +48 -0
- data/lib/irb/cmd/show_source.rb +5 -4
- data/lib/irb/color.rb +3 -9
- data/lib/irb/color_printer.rb +6 -1
- data/lib/irb/completion.rb +1 -34
- data/lib/irb/ext/loader.rb +1 -24
- data/lib/irb/ext/tracer.rb +1 -2
- data/lib/irb/extend-command.rb +12 -84
- data/lib/irb/help.rb +1 -3
- data/lib/irb/input-method.rb +4 -3
- data/lib/irb/inspector.rb +1 -2
- data/lib/irb/locale.rb +10 -43
- data/lib/irb/ruby-lex.rb +78 -100
- data/lib/irb/version.rb +2 -2
- data/lib/irb.rb +2 -13
- metadata +5 -6
- data/lib/irb/lc/ja/encoding_aliases.rb +0 -13
- data/lib/irb/magic-file.rb +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa3c9603f48d730988d34f454a10b58021caa677ab8832d9764e39e61bb49abb
|
4
|
+
data.tar.gz: c46d1e32c81a8f22593e174af095070159af6a61508c97b3ef4b0b9d28301d58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e99185c909180d01a3310f7db11437181268b930d267f2fe365c06cd7a442ad3a8cdf7d5863fb19e17885a23aad46b993a2e5c21fb8632ff2f91285e469be4b
|
7
|
+
data.tar.gz: 44978be86d00d0fc435e81e4cadc5abad08d47519a189db02e34d7eb3435e9ac0cc0adf470e845edba1e7d866574298e1b7b8bba5190d8be538c396cd0179d07
|
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# IRB
|
2
2
|
|
3
|
+
[](https://badge.fury.io/rb/irb)
|
4
|
+
[](https://github.com/ruby/irb/actions/workflows/test.yml)
|
5
|
+
|
3
6
|
IRB stands for "interactive Ruby" and is a tool to interactively execute Ruby expressions read from the standard input.
|
4
7
|
|
5
8
|
The `irb` command from your shell will start the interpreter.
|
data/irb.gemspec
CHANGED
@@ -39,7 +39,7 @@ Gem::Specification.new do |spec|
|
|
39
39
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
40
40
|
spec.require_paths = ["lib"]
|
41
41
|
|
42
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 2.
|
42
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.7")
|
43
43
|
|
44
44
|
spec.add_dependency "reline", ">= 0.3.0"
|
45
45
|
end
|
data/lib/irb/cmd/help.rb
CHANGED
@@ -1,57 +1,23 @@
|
|
1
|
-
# frozen_string_literal:
|
2
|
-
#
|
3
|
-
# help.rb - helper using ri
|
4
|
-
#
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
|
-
require_relative "
|
3
|
+
require_relative "show_doc"
|
7
4
|
|
8
5
|
module IRB
|
9
|
-
# :stopdoc:
|
10
|
-
|
11
6
|
module ExtendCommand
|
12
|
-
class Help <
|
13
|
-
class << self
|
14
|
-
def transform_args(args)
|
15
|
-
# Return a string literal as is for backward compatibility
|
16
|
-
if args.empty? || string_literal?(args)
|
17
|
-
args
|
18
|
-
else # Otherwise, consider the input as a String for convenience
|
19
|
-
args.strip.dump
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
7
|
+
class Help < ShowDoc
|
24
8
|
category "Context"
|
25
|
-
description "Enter the mode to look up RI documents."
|
9
|
+
description "[DEPRECATED] Enter the mode to look up RI documents."
|
10
|
+
|
11
|
+
DEPRECATION_MESSAGE = <<~MSG
|
12
|
+
[Deprecation] The `help` command will be repurposed to display command help in the future.
|
13
|
+
For RI document lookup, please use the `show_doc` command instead.
|
14
|
+
For command help, please use `show_cmds` for now.
|
15
|
+
MSG
|
26
16
|
|
27
17
|
def execute(*names)
|
28
|
-
|
29
|
-
|
30
|
-
IRB::ExtendCommand::Help.const_set(:Ri, RDoc::RI::Driver.new(opts))
|
31
|
-
rescue LoadError, SystemExit
|
32
|
-
IRB::ExtendCommand::Help.remove_method(:execute)
|
33
|
-
# raise NoMethodError in ensure
|
34
|
-
else
|
35
|
-
def execute(*names)
|
36
|
-
if names.empty?
|
37
|
-
Ri.interactive
|
38
|
-
return
|
39
|
-
end
|
40
|
-
names.each do |name|
|
41
|
-
begin
|
42
|
-
Ri.display_name(name.to_s)
|
43
|
-
rescue RDoc::RI::Error
|
44
|
-
puts $!.message
|
45
|
-
end
|
46
|
-
end
|
47
|
-
nil
|
48
|
-
end
|
49
|
-
nil
|
50
|
-
ensure
|
51
|
-
execute(*names)
|
18
|
+
warn DEPRECATION_MESSAGE
|
19
|
+
super
|
52
20
|
end
|
53
21
|
end
|
54
22
|
end
|
55
|
-
|
56
|
-
# :startdoc:
|
57
23
|
end
|
data/lib/irb/cmd/ls.rb
CHANGED
@@ -39,8 +39,12 @@ module IRB
|
|
39
39
|
def dump_methods(o, klass, obj)
|
40
40
|
singleton_class = begin obj.singleton_class; rescue TypeError; nil end
|
41
41
|
dumped_mods = Array.new
|
42
|
+
ancestors = klass.ancestors
|
43
|
+
ancestors = ancestors.reject { |c| c >= Object } if klass < Object
|
44
|
+
singleton_ancestors = (singleton_class&.ancestors || []).reject { |c| c >= Class }
|
45
|
+
|
42
46
|
# singleton_class' ancestors should be at the front
|
43
|
-
maps = class_method_map(
|
47
|
+
maps = class_method_map(singleton_ancestors, dumped_mods) + class_method_map(ancestors, dumped_mods)
|
44
48
|
maps.each do |mod, methods|
|
45
49
|
name = mod == singleton_class ? "#{klass}.methods" : "#{mod}#methods"
|
46
50
|
o.dump(name, methods)
|
@@ -49,7 +53,6 @@ module IRB
|
|
49
53
|
|
50
54
|
def class_method_map(classes, dumped_mods)
|
51
55
|
dumped_methods = Array.new
|
52
|
-
classes = classes.reject { |mod| mod >= Object }
|
53
56
|
classes.map do |mod|
|
54
57
|
next if dumped_mods.include? mod
|
55
58
|
|
data/lib/irb/cmd/nop.rb
CHANGED
@@ -30,20 +30,11 @@ module IRB
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
puts e.message
|
39
|
-
end
|
40
|
-
else
|
41
|
-
def self.execute(conf, *opts, &block)
|
42
|
-
command = new(conf)
|
43
|
-
command.execute(*opts, &block)
|
44
|
-
rescue CommandArgumentError => e
|
45
|
-
puts e.message
|
46
|
-
end
|
33
|
+
def self.execute(conf, *opts, **kwargs, &block)
|
34
|
+
command = new(conf)
|
35
|
+
command.execute(*opts, **kwargs, &block)
|
36
|
+
rescue CommandArgumentError => e
|
37
|
+
puts e.message
|
47
38
|
end
|
48
39
|
|
49
40
|
def initialize(conf)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "nop"
|
4
|
+
|
5
|
+
module IRB
|
6
|
+
module ExtendCommand
|
7
|
+
class ShowDoc < Nop
|
8
|
+
class << self
|
9
|
+
def transform_args(args)
|
10
|
+
# Return a string literal as is for backward compatibility
|
11
|
+
if args.empty? || string_literal?(args)
|
12
|
+
args
|
13
|
+
else # Otherwise, consider the input as a String for convenience
|
14
|
+
args.strip.dump
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
category "Context"
|
20
|
+
description "Enter the mode to look up RI documents."
|
21
|
+
|
22
|
+
def execute(*names)
|
23
|
+
require 'rdoc/ri/driver'
|
24
|
+
|
25
|
+
unless ShowDoc.const_defined?(:Ri)
|
26
|
+
opts = RDoc::RI::Driver.process_args([])
|
27
|
+
ShowDoc.const_set(:Ri, RDoc::RI::Driver.new(opts))
|
28
|
+
end
|
29
|
+
|
30
|
+
if names.empty?
|
31
|
+
Ri.interactive
|
32
|
+
else
|
33
|
+
names.each do |name|
|
34
|
+
begin
|
35
|
+
Ri.display_name(name.to_s)
|
36
|
+
rescue RDoc::RI::Error
|
37
|
+
puts $!.message
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
nil
|
43
|
+
rescue LoadError, SystemExit
|
44
|
+
warn "Can't display document because `rdoc` is not installed."
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/irb/cmd/show_source.rb
CHANGED
@@ -27,17 +27,18 @@ module IRB
|
|
27
27
|
when /\A[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name
|
28
28
|
eval(str, irb_context.workspace.binding) # trigger autoload
|
29
29
|
base = irb_context.workspace.binding.receiver.yield_self { |r| r.is_a?(Module) ? r : Object }
|
30
|
-
file, line = base.const_source_location(str)
|
30
|
+
file, line = base.const_source_location(str)
|
31
31
|
when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
|
32
32
|
owner = eval(Regexp.last_match[:owner], irb_context.workspace.binding)
|
33
33
|
method = Regexp.last_match[:method]
|
34
|
-
if owner.respond_to?(:instance_method)
|
35
|
-
|
34
|
+
if owner.respond_to?(:instance_method)
|
35
|
+
methods = owner.instance_methods + owner.private_instance_methods
|
36
|
+
file, line = owner.instance_method(method).source_location if methods.include?(method.to_sym)
|
36
37
|
end
|
37
38
|
when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method
|
38
39
|
receiver = eval(Regexp.last_match[:receiver] || 'self', irb_context.workspace.binding)
|
39
40
|
method = Regexp.last_match[:method]
|
40
|
-
file, line = receiver.method(method).source_location if receiver.respond_to?(method)
|
41
|
+
file, line = receiver.method(method).source_location if receiver.respond_to?(method, true)
|
41
42
|
end
|
42
43
|
if file && line
|
43
44
|
Source.new(file: file, first_line: line, last_line: find_end(file, line, irb_context))
|
data/lib/irb/color.rb
CHANGED
@@ -197,15 +197,9 @@ module IRB # :nodoc:
|
|
197
197
|
end
|
198
198
|
end
|
199
199
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
on_scan.call(elem)
|
204
|
-
end
|
205
|
-
else
|
206
|
-
lexer.parse.sort_by(&:pos).each do |elem|
|
207
|
-
on_scan.call(elem)
|
208
|
-
end
|
200
|
+
lexer.scan.each do |elem|
|
201
|
+
next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message
|
202
|
+
on_scan.call(elem)
|
209
203
|
end
|
210
204
|
# yield uncolorable DATA section
|
211
205
|
yield(nil, inner_code.byteslice(byte_pos...inner_code.bytesize), nil) if byte_pos < inner_code.bytesize
|
data/lib/irb/color_printer.rb
CHANGED
@@ -4,6 +4,9 @@ require_relative 'color'
|
|
4
4
|
|
5
5
|
module IRB
|
6
6
|
class ColorPrinter < ::PP
|
7
|
+
METHOD_RESPOND_TO = Object.instance_method(:respond_to?)
|
8
|
+
METHOD_INSPECT = Object.instance_method(:inspect)
|
9
|
+
|
7
10
|
class << self
|
8
11
|
def pp(obj, out = $>, width = screen_width)
|
9
12
|
q = ColorPrinter.new(out, width)
|
@@ -22,9 +25,11 @@ module IRB
|
|
22
25
|
end
|
23
26
|
|
24
27
|
def pp(obj)
|
25
|
-
if obj
|
28
|
+
if String === obj
|
26
29
|
# Avoid calling Ruby 2.4+ String#pretty_print that splits a string by "\n"
|
27
30
|
text(obj.inspect)
|
31
|
+
elsif !METHOD_RESPOND_TO.bind(obj).call(:inspect)
|
32
|
+
text(METHOD_INSPECT.bind(obj).call)
|
28
33
|
else
|
29
34
|
super
|
30
35
|
end
|
data/lib/irb/completion.rb
CHANGED
@@ -58,19 +58,11 @@ module IRB
|
|
58
58
|
|
59
59
|
BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
|
60
60
|
|
61
|
-
def self.absolute_path?(p) # TODO Remove this method after 2.6 EOL.
|
62
|
-
if File.respond_to?(:absolute_path?)
|
63
|
-
File.absolute_path?(p)
|
64
|
-
else
|
65
|
-
File.absolute_path(p) == p
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
61
|
GEM_PATHS =
|
70
62
|
if defined?(Gem::Specification)
|
71
63
|
Gem::Specification.latest_specs(true).map { |s|
|
72
64
|
s.require_paths.map { |p|
|
73
|
-
if absolute_path?(p)
|
65
|
+
if File.absolute_path?(p)
|
74
66
|
p
|
75
67
|
else
|
76
68
|
File.join(s.full_gem_path, p)
|
@@ -450,30 +442,5 @@ module IRB
|
|
450
442
|
end
|
451
443
|
end
|
452
444
|
end
|
453
|
-
|
454
|
-
def self.ignored_modules
|
455
|
-
# We could cache the result, but this is very fast already.
|
456
|
-
# By using this approach, we avoid Module#name calls, which are
|
457
|
-
# relatively slow when there are a lot of anonymous modules defined.
|
458
|
-
s = {}
|
459
|
-
|
460
|
-
scanner = lambda do |m|
|
461
|
-
next if s.include?(m) # IRB::ExtendCommandBundle::EXCB recurses.
|
462
|
-
s[m] = true
|
463
|
-
m.constants(false).each do |c|
|
464
|
-
value = m.const_get(c)
|
465
|
-
scanner.call(value) if value.is_a?(Module)
|
466
|
-
end
|
467
|
-
end
|
468
|
-
|
469
|
-
%i(IRB RubyLex).each do |sym|
|
470
|
-
next unless Object.const_defined?(sym)
|
471
|
-
scanner.call(Object.const_get(sym))
|
472
|
-
end
|
473
|
-
|
474
|
-
s.delete(IRB::Context) if defined?(IRB::Context)
|
475
|
-
|
476
|
-
s
|
477
|
-
end
|
478
445
|
end
|
479
446
|
end
|
data/lib/irb/ext/loader.rb
CHANGED
@@ -24,31 +24,8 @@ module IRB # :nodoc:
|
|
24
24
|
load_file(path, priv)
|
25
25
|
end
|
26
26
|
|
27
|
-
if File.respond_to?(:absolute_path?)
|
28
|
-
def absolute_path?(path)
|
29
|
-
File.absolute_path?(path)
|
30
|
-
end
|
31
|
-
else
|
32
|
-
separator =
|
33
|
-
if File::ALT_SEPARATOR
|
34
|
-
"[#{Regexp.quote(File::SEPARATOR + File::ALT_SEPARATOR)}]"
|
35
|
-
else
|
36
|
-
File::SEPARATOR
|
37
|
-
end
|
38
|
-
ABSOLUTE_PATH_PATTERN = # :nodoc:
|
39
|
-
case Dir.pwd
|
40
|
-
when /\A\w:/, /\A#{separator}{2}/
|
41
|
-
/\A(?:\w:|#{separator})#{separator}/
|
42
|
-
else
|
43
|
-
/\A#{separator}/
|
44
|
-
end
|
45
|
-
def absolute_path?(path)
|
46
|
-
ABSOLUTE_PATH_PATTERN =~ path
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
27
|
def search_file_from_ruby_path(fn) # :nodoc:
|
51
|
-
if absolute_path?(fn)
|
28
|
+
if File.absolute_path?(fn)
|
52
29
|
return fn if File.exist?(fn)
|
53
30
|
return nil
|
54
31
|
end
|
data/lib/irb/ext/tracer.rb
CHANGED
@@ -7,9 +7,8 @@
|
|
7
7
|
begin
|
8
8
|
require "tracer"
|
9
9
|
rescue LoadError
|
10
|
-
$stderr.puts "Tracer extension of IRB is enabled but tracer gem
|
10
|
+
$stderr.puts "Tracer extension of IRB is enabled but tracer gem wasn't found."
|
11
11
|
module IRB
|
12
|
-
TracerLoadError = true
|
13
12
|
class Context
|
14
13
|
def use_tracer=(opt)
|
15
14
|
# do nothing
|
data/lib/irb/extend-command.rb
CHANGED
@@ -157,10 +157,14 @@ module IRB # :nodoc:
|
|
157
157
|
|
158
158
|
[
|
159
159
|
:irb_help, :Help, "cmd/help",
|
160
|
-
[:show_doc, NO_OVERRIDE],
|
161
160
|
[:help, NO_OVERRIDE],
|
162
161
|
],
|
163
162
|
|
163
|
+
[
|
164
|
+
:irb_show_doc, :ShowDoc, "cmd/show_doc",
|
165
|
+
[:show_doc, NO_OVERRIDE],
|
166
|
+
],
|
167
|
+
|
164
168
|
[
|
165
169
|
:irb_info, :IrbInfo, "cmd/irb_info"
|
166
170
|
],
|
@@ -246,7 +250,7 @@ module IRB # :nodoc:
|
|
246
250
|
#
|
247
251
|
# The optional +load_file+ parameter will be required within the method
|
248
252
|
# definition.
|
249
|
-
def self.def_extend_command(cmd_name, cmd_class, load_file
|
253
|
+
def self.def_extend_command(cmd_name, cmd_class, load_file, *aliases)
|
250
254
|
case cmd_class
|
251
255
|
when Symbol
|
252
256
|
cmd_class = cmd_class.id2name
|
@@ -255,34 +259,12 @@ module IRB # :nodoc:
|
|
255
259
|
cmd_class = cmd_class.name
|
256
260
|
end
|
257
261
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s }
|
265
|
-
args << "*opts#{kwargs}" if arity < 0
|
266
|
-
args << "&block"
|
267
|
-
args = args.join(", ")
|
268
|
-
line = __LINE__; eval %[
|
269
|
-
unless singleton_class.class_variable_defined?(:@@#{cmd_name}_)
|
270
|
-
singleton_class.class_variable_set(:@@#{cmd_name}_, true)
|
271
|
-
def self.#{cmd_name}_(\#{args})
|
272
|
-
::IRB::ExtendCommand::#{cmd_class}.execute(irb_context, \#{args})
|
273
|
-
end
|
274
|
-
end
|
275
|
-
], nil, __FILE__, line
|
276
|
-
__send__ :#{cmd_name}_, *opts#{kwargs}, &b
|
277
|
-
end
|
278
|
-
], nil, __FILE__, line
|
279
|
-
else
|
280
|
-
line = __LINE__; eval %[
|
281
|
-
def #{cmd_name}(*opts, &b)
|
282
|
-
::IRB::ExtendCommand::#{cmd_class}.execute(irb_context, *opts, &b)
|
283
|
-
end
|
284
|
-
], nil, __FILE__, line
|
285
|
-
end
|
262
|
+
line = __LINE__; eval %[
|
263
|
+
def #{cmd_name}(*opts, **kwargs, &b)
|
264
|
+
Kernel.require_relative "#{load_file}"
|
265
|
+
::IRB::ExtendCommand::#{cmd_class}.execute(irb_context, *opts, **kwargs, &b)
|
266
|
+
end
|
267
|
+
], nil, __FILE__, line
|
286
268
|
|
287
269
|
for ali, flag in aliases
|
288
270
|
@ALIASES.push [ali, cmd_name, flag]
|
@@ -371,58 +353,4 @@ module IRB # :nodoc:
|
|
371
353
|
|
372
354
|
CE.install_extend_commands
|
373
355
|
end
|
374
|
-
|
375
|
-
# A convenience module for extending Ruby methods.
|
376
|
-
module MethodExtender
|
377
|
-
# Extends the given +base_method+ with a prefix call to the given
|
378
|
-
# +extend_method+.
|
379
|
-
def def_pre_proc(base_method, extend_method)
|
380
|
-
base_method = base_method.to_s
|
381
|
-
extend_method = extend_method.to_s
|
382
|
-
|
383
|
-
alias_name = new_alias_name(base_method)
|
384
|
-
module_eval %[
|
385
|
-
alias_method alias_name, base_method
|
386
|
-
def #{base_method}(*opts)
|
387
|
-
__send__ :#{extend_method}, *opts
|
388
|
-
__send__ :#{alias_name}, *opts
|
389
|
-
end
|
390
|
-
]
|
391
|
-
end
|
392
|
-
|
393
|
-
# Extends the given +base_method+ with a postfix call to the given
|
394
|
-
# +extend_method+.
|
395
|
-
def def_post_proc(base_method, extend_method)
|
396
|
-
base_method = base_method.to_s
|
397
|
-
extend_method = extend_method.to_s
|
398
|
-
|
399
|
-
alias_name = new_alias_name(base_method)
|
400
|
-
module_eval %[
|
401
|
-
alias_method alias_name, base_method
|
402
|
-
def #{base_method}(*opts)
|
403
|
-
__send__ :#{alias_name}, *opts
|
404
|
-
__send__ :#{extend_method}, *opts
|
405
|
-
end
|
406
|
-
]
|
407
|
-
end
|
408
|
-
|
409
|
-
# Returns a unique method name to use as an alias for the given +name+.
|
410
|
-
#
|
411
|
-
# Usually returns <code>#{prefix}#{name}#{postfix}<num></code>, example:
|
412
|
-
#
|
413
|
-
# new_alias_name('foo') #=> __alias_of__foo__
|
414
|
-
# def bar; end
|
415
|
-
# new_alias_name('bar') #=> __alias_of__bar__2
|
416
|
-
def new_alias_name(name, prefix = "__alias_of__", postfix = "__")
|
417
|
-
base_name = "#{prefix}#{name}#{postfix}"
|
418
|
-
all_methods = instance_methods(true) + private_instance_methods(true)
|
419
|
-
same_methods = all_methods.grep(/^#{Regexp.quote(base_name)}[0-9]*$/)
|
420
|
-
return base_name if same_methods.empty?
|
421
|
-
no = same_methods.size
|
422
|
-
while !same_methods.include?(alias_name = base_name + no)
|
423
|
-
no += 1
|
424
|
-
end
|
425
|
-
alias_name
|
426
|
-
end
|
427
|
-
end
|
428
356
|
end
|
data/lib/irb/help.rb
CHANGED
@@ -4,15 +4,13 @@
|
|
4
4
|
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
5
5
|
#
|
6
6
|
|
7
|
-
require_relative 'magic-file'
|
8
|
-
|
9
7
|
module IRB
|
10
8
|
# Outputs the irb help message, see IRB@Command+line+options.
|
11
9
|
def IRB.print_usage
|
12
10
|
lc = IRB.conf[:LC_MESSAGES]
|
13
11
|
path = lc.find("irb/help-message")
|
14
12
|
space_line = false
|
15
|
-
|
13
|
+
File.open(path){|f|
|
16
14
|
f.each_line do |l|
|
17
15
|
if /^\s*$/ =~ l
|
18
16
|
lc.puts l unless space_line
|
data/lib/irb/input-method.rb
CHANGED
@@ -5,7 +5,6 @@
|
|
5
5
|
#
|
6
6
|
|
7
7
|
require_relative 'src_encoding'
|
8
|
-
require_relative 'magic-file'
|
9
8
|
require_relative 'completion'
|
10
9
|
require 'io/console'
|
11
10
|
require 'reline'
|
@@ -132,7 +131,7 @@ module IRB
|
|
132
131
|
# Creates a new input method object
|
133
132
|
def initialize(file)
|
134
133
|
super
|
135
|
-
@io = file.is_a?(IO) ? file :
|
134
|
+
@io = file.is_a?(IO) ? file : File.open(file)
|
136
135
|
@external_encoding = @io.external_encoding
|
137
136
|
end
|
138
137
|
# The file name of this input method, usually given during initialization.
|
@@ -399,8 +398,10 @@ module IRB
|
|
399
398
|
formatter = RDoc::Markup::ToAnsi.new
|
400
399
|
formatter.width = width
|
401
400
|
dialog.trap_key = alt_d
|
402
|
-
|
401
|
+
mod_key = RUBY_PLATFORM.match?(/darwin/) ? "Option" : "Alt"
|
402
|
+
message = "Press #{mod_key}+d to read the full document"
|
403
403
|
contents = [message] + doc.accept(formatter).split("\n")
|
404
|
+
contents = contents.take(preferred_dialog_height) if respond_to?(:preferred_dialog_height)
|
404
405
|
|
405
406
|
y = cursor_pos_to_render.y
|
406
407
|
DialogRenderInfo.new(pos: Reline::CursorPos.new(x, y), contents: contents, width: width, bg_color: '49')
|
data/lib/irb/inspector.rb
CHANGED
@@ -98,8 +98,7 @@ module IRB # :nodoc:
|
|
98
98
|
puts "An error occurred when inspecting the object: #{e.inspect}"
|
99
99
|
|
100
100
|
begin
|
101
|
-
|
102
|
-
puts "Result of Kernel#inspect: #{KERNEL_INSPECT.bind(v).call}"
|
101
|
+
puts "Result of Kernel#inspect: #{KERNEL_INSPECT.bind_call(v)}"
|
103
102
|
''
|
104
103
|
rescue => e
|
105
104
|
puts "An error occurred when running Kernel#inspect: #{e.inspect}"
|
data/lib/irb/locale.rb
CHANGED
@@ -15,7 +15,11 @@ module IRB # :nodoc:
|
|
15
15
|
]x
|
16
16
|
LOCALE_DIR = "/lc/"
|
17
17
|
|
18
|
-
|
18
|
+
LEGACY_ENCODING_ALIAS_MAP = {
|
19
|
+
'ujis' => Encoding::EUC_JP,
|
20
|
+
'euc' => Encoding::EUC_JP
|
21
|
+
}
|
22
|
+
|
19
23
|
@@loaded = []
|
20
24
|
|
21
25
|
def initialize(locale = nil)
|
@@ -26,11 +30,11 @@ module IRB # :nodoc:
|
|
26
30
|
@lang, @territory, @encoding_name, @modifier = m[:language], m[:territory], m[:codeset], m[:modifier]
|
27
31
|
|
28
32
|
if @encoding_name
|
29
|
-
|
30
|
-
if @encoding = @@legacy_encoding_alias_map[@encoding_name]
|
33
|
+
if @encoding = LEGACY_ENCODING_ALIAS_MAP[@encoding_name]
|
31
34
|
warn(("%s is obsolete. use %s" % ["#{@lang}_#{@territory}.#{@encoding_name}", "#{@lang}_#{@territory}.#{@encoding.name}"]), uplevel: 1)
|
35
|
+
else
|
36
|
+
@encoding = Encoding.find(@encoding_name) rescue nil
|
32
37
|
end
|
33
|
-
@encoding = Encoding.find(@encoding_name) rescue nil
|
34
38
|
end
|
35
39
|
end
|
36
40
|
@encoding ||= (Encoding.find('locale') rescue Encoding::ASCII_8BIT)
|
@@ -78,39 +82,12 @@ module IRB # :nodoc:
|
|
78
82
|
super(*ary)
|
79
83
|
end
|
80
84
|
|
81
|
-
def
|
82
|
-
rex = Regexp.new("lc/#{Regexp.quote(file)}\.(so|o|sl|rb)?")
|
83
|
-
return false if $".find{|f| f =~ rex}
|
84
|
-
|
85
|
-
case file
|
86
|
-
when /\.rb$/
|
87
|
-
begin
|
88
|
-
load(file, priv)
|
89
|
-
$".push file
|
90
|
-
return true
|
91
|
-
rescue LoadError
|
92
|
-
end
|
93
|
-
when /\.(so|o|sl)$/
|
94
|
-
return super
|
95
|
-
end
|
96
|
-
|
97
|
-
begin
|
98
|
-
load(f = file + ".rb")
|
99
|
-
$".push f #"
|
100
|
-
return true
|
101
|
-
rescue LoadError
|
102
|
-
return ruby_require(file)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
alias toplevel_load load
|
107
|
-
|
108
|
-
def load(file, priv=nil)
|
85
|
+
def load(file)
|
109
86
|
found = find(file)
|
110
87
|
if found
|
111
88
|
unless @@loaded.include?(found)
|
112
89
|
@@loaded << found # cache
|
113
|
-
|
90
|
+
Kernel.load(found)
|
114
91
|
end
|
115
92
|
else
|
116
93
|
raise LoadError, "No such file to load -- #{file}"
|
@@ -129,16 +106,6 @@ module IRB # :nodoc:
|
|
129
106
|
end
|
130
107
|
end
|
131
108
|
|
132
|
-
private
|
133
|
-
def real_load(path, priv)
|
134
|
-
src = MagicFile.open(path){|f| f.read}
|
135
|
-
if priv
|
136
|
-
eval("self", TOPLEVEL_BINDING).extend(Module.new {eval(src, nil, path)})
|
137
|
-
else
|
138
|
-
eval(src, TOPLEVEL_BINDING, path)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
109
|
# @param paths load paths in which IRB find a localized file.
|
143
110
|
# @param dir directory
|
144
111
|
# @param file basename to be localized
|
data/lib/irb/ruby-lex.rb
CHANGED
@@ -18,10 +18,7 @@ class RubyLex
|
|
18
18
|
|
19
19
|
def initialize(context)
|
20
20
|
@context = context
|
21
|
-
@
|
22
|
-
@indent = 0
|
23
|
-
@continue = false
|
24
|
-
@line = ""
|
21
|
+
@line_no = 1
|
25
22
|
@prompt = nil
|
26
23
|
end
|
27
24
|
|
@@ -42,8 +39,17 @@ class RubyLex
|
|
42
39
|
result
|
43
40
|
end
|
44
41
|
|
42
|
+
def single_line_command?(code)
|
43
|
+
command = code.split(/\s/, 2).first
|
44
|
+
@context.symbol_alias?(command) || @context.transform_args?(command)
|
45
|
+
end
|
46
|
+
|
45
47
|
# io functions
|
46
|
-
def set_input(
|
48
|
+
def set_input(&block)
|
49
|
+
@input = block
|
50
|
+
end
|
51
|
+
|
52
|
+
def configure_io(io)
|
47
53
|
@io = io
|
48
54
|
if @io.respond_to?(:check_termination)
|
49
55
|
@io.check_termination do |code|
|
@@ -61,14 +67,9 @@ class RubyLex
|
|
61
67
|
end
|
62
68
|
else
|
63
69
|
# Accept any single-line input for symbol aliases or commands that transform args
|
64
|
-
|
65
|
-
if @context.symbol_alias?(command) || @context.transform_args?(command)
|
66
|
-
next true
|
67
|
-
end
|
70
|
+
next true if single_line_command?(code)
|
68
71
|
|
69
|
-
|
70
|
-
tokens = self.class.ripper_lex_without_warning(code, context: @context)
|
71
|
-
ltype, indent, continue, code_block_open = check_state(code, tokens)
|
72
|
+
ltype, indent, continue, code_block_open = check_code_state(code)
|
72
73
|
if ltype or indent > 0 or continue or code_block_open
|
73
74
|
false
|
74
75
|
else
|
@@ -112,10 +113,22 @@ class RubyLex
|
|
112
113
|
end
|
113
114
|
end
|
114
115
|
|
115
|
-
if
|
116
|
-
@
|
117
|
-
|
118
|
-
|
116
|
+
if @io.respond_to?(:auto_indent) and @context.auto_indent_mode
|
117
|
+
@io.auto_indent do |lines, line_index, byte_pointer, is_newline|
|
118
|
+
if is_newline
|
119
|
+
@tokens = self.class.ripper_lex_without_warning(lines[0..line_index].join("\n"), context: @context)
|
120
|
+
prev_spaces = find_prev_spaces(line_index)
|
121
|
+
depth_difference = check_newline_depth_difference
|
122
|
+
depth_difference = 0 if depth_difference < 0
|
123
|
+
prev_spaces + depth_difference * 2
|
124
|
+
else
|
125
|
+
code = line_index.zero? ? '' : lines[0..(line_index - 1)].map{ |l| l + "\n" }.join
|
126
|
+
last_line = lines[line_index]&.byteslice(0, byte_pointer)
|
127
|
+
code += last_line if last_line
|
128
|
+
@tokens = self.class.ripper_lex_without_warning(code, context: @context)
|
129
|
+
check_corresponding_token_depth(lines, line_index)
|
130
|
+
end
|
131
|
+
end
|
119
132
|
end
|
120
133
|
end
|
121
134
|
|
@@ -148,19 +161,15 @@ class RubyLex
|
|
148
161
|
|
149
162
|
compile_with_errors_suppressed(code, line_no: line_no) do |inner_code, line_no|
|
150
163
|
lexer = Ripper::Lexer.new(inner_code, '-', line_no)
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
if
|
157
|
-
|
158
|
-
|
159
|
-
tokens << t
|
160
|
-
end
|
164
|
+
lexer.scan.each_with_object([]) do |t, tokens|
|
165
|
+
next if t.pos.first == 0
|
166
|
+
prev_tk = tokens.last
|
167
|
+
position_overlapped = prev_tk && t.pos[0] == prev_tk.pos[0] && t.pos[1] < prev_tk.pos[1] + prev_tk.tok.bytesize
|
168
|
+
if position_overlapped
|
169
|
+
tokens[-1] = t if ERROR_TOKENS.include?(prev_tk.event) && !ERROR_TOKENS.include?(t.event)
|
170
|
+
else
|
171
|
+
tokens << t
|
161
172
|
end
|
162
|
-
else
|
163
|
-
lexer.parse.reject { |it| it.pos.first == 0 }.sort_by(&:pos)
|
164
173
|
end
|
165
174
|
end
|
166
175
|
ensure
|
@@ -188,26 +197,6 @@ class RubyLex
|
|
188
197
|
prev_spaces
|
189
198
|
end
|
190
199
|
|
191
|
-
def set_auto_indent
|
192
|
-
if @io.respond_to?(:auto_indent) and @context.auto_indent_mode
|
193
|
-
@io.auto_indent do |lines, line_index, byte_pointer, is_newline|
|
194
|
-
if is_newline
|
195
|
-
@tokens = self.class.ripper_lex_without_warning(lines[0..line_index].join("\n"), context: @context)
|
196
|
-
prev_spaces = find_prev_spaces(line_index)
|
197
|
-
depth_difference = check_newline_depth_difference
|
198
|
-
depth_difference = 0 if depth_difference < 0
|
199
|
-
prev_spaces + depth_difference * 2
|
200
|
-
else
|
201
|
-
code = line_index.zero? ? '' : lines[0..(line_index - 1)].map{ |l| l + "\n" }.join
|
202
|
-
last_line = lines[line_index]&.byteslice(0, byte_pointer)
|
203
|
-
code += last_line if last_line
|
204
|
-
@tokens = self.class.ripper_lex_without_warning(code, context: @context)
|
205
|
-
check_corresponding_token_depth(lines, line_index)
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
200
|
def check_state(code, tokens)
|
212
201
|
ltype = process_literal_type(tokens)
|
213
202
|
indent = process_nesting_level(tokens)
|
@@ -218,67 +207,56 @@ class RubyLex
|
|
218
207
|
[ltype, indent, continue, code_block_open]
|
219
208
|
end
|
220
209
|
|
221
|
-
def
|
222
|
-
|
223
|
-
|
224
|
-
|
210
|
+
def check_code_state(code)
|
211
|
+
check_target_code = code.gsub(/\s*\z/, '').concat("\n")
|
212
|
+
tokens = self.class.ripper_lex_without_warning(check_target_code, context: @context)
|
213
|
+
check_state(check_target_code, tokens)
|
225
214
|
end
|
226
215
|
|
227
|
-
def
|
228
|
-
|
229
|
-
@indent
|
230
|
-
@continue = false
|
231
|
-
@line = ""
|
232
|
-
@exp_line_no = @line_no
|
233
|
-
@code_block_open = false
|
216
|
+
def save_prompt_to_context_io(ltype, indent, continue, line_num_offset)
|
217
|
+
# Implicitly saves prompt string to `@context.io.prompt`. This will be used in the next `@input.call`.
|
218
|
+
@prompt.call(ltype, indent, continue, @line_no + line_num_offset)
|
234
219
|
end
|
235
220
|
|
236
|
-
def
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
end
|
250
|
-
@line.concat l
|
251
|
-
if @code_block_open or @ltype or @continue or @indent > 0
|
252
|
-
next
|
253
|
-
end
|
254
|
-
end
|
255
|
-
if @line != "\n"
|
256
|
-
@line.force_encoding(@io.encoding)
|
257
|
-
yield @line, @exp_line_no
|
258
|
-
end
|
259
|
-
raise TerminateLineInput if @io.eof?
|
260
|
-
@line = ''
|
261
|
-
@exp_line_no = @line_no
|
262
|
-
|
263
|
-
@indent = 0
|
264
|
-
rescue TerminateLineInput
|
265
|
-
initialize_input
|
266
|
-
prompt
|
267
|
-
end
|
221
|
+
def readmultiline
|
222
|
+
save_prompt_to_context_io(nil, 0, false, 0)
|
223
|
+
|
224
|
+
# multiline
|
225
|
+
return @input.call if @io.respond_to?(:check_termination)
|
226
|
+
|
227
|
+
# nomultiline
|
228
|
+
code = ''
|
229
|
+
line_offset = 0
|
230
|
+
loop do
|
231
|
+
line = @input.call
|
232
|
+
unless line
|
233
|
+
return code.empty? ? nil : code
|
268
234
|
end
|
235
|
+
|
236
|
+
code << line
|
237
|
+
# Accept any single-line input for symbol aliases or commands that transform args
|
238
|
+
return code if single_line_command?(code)
|
239
|
+
|
240
|
+
ltype, indent, continue, code_block_open = check_code_state(code)
|
241
|
+
return code unless ltype or indent > 0 or continue or code_block_open
|
242
|
+
|
243
|
+
line_offset += 1
|
244
|
+
save_prompt_to_context_io(ltype, indent, continue, line_offset)
|
269
245
|
end
|
270
246
|
end
|
271
247
|
|
272
|
-
def
|
273
|
-
|
274
|
-
|
275
|
-
|
248
|
+
def each_top_level_statement
|
249
|
+
loop do
|
250
|
+
code = readmultiline
|
251
|
+
break unless code
|
252
|
+
|
253
|
+
if code != "\n"
|
254
|
+
code.force_encoding(@io.encoding)
|
255
|
+
yield code, @line_no
|
256
|
+
end
|
257
|
+
@line_no += code.count("\n")
|
258
|
+
rescue TerminateLineInput
|
276
259
|
end
|
277
|
-
code = @line + (line.nil? ? '' : line)
|
278
|
-
code.gsub!(/\s*\z/, '').concat("\n")
|
279
|
-
@tokens = self.class.ripper_lex_without_warning(code, context: @context)
|
280
|
-
@ltype, @indent, @continue, @code_block_open = check_state(code, @tokens)
|
281
|
-
line
|
282
260
|
end
|
283
261
|
|
284
262
|
def process_continue(tokens)
|
data/lib/irb/version.rb
CHANGED
data/lib/irb.rb
CHANGED
@@ -416,11 +416,6 @@ module IRB
|
|
416
416
|
irb.run(@CONF)
|
417
417
|
end
|
418
418
|
|
419
|
-
# Calls each event hook of <code>IRB.conf[:AT_EXIT]</code> when the current session quits.
|
420
|
-
def IRB.irb_at_exit
|
421
|
-
@CONF[:AT_EXIT].each{|hook| hook.call}
|
422
|
-
end
|
423
|
-
|
424
419
|
# Quits irb
|
425
420
|
def IRB.irb_exit(irb, ret)
|
426
421
|
throw :IRB_EXIT, ret
|
@@ -542,7 +537,7 @@ module IRB
|
|
542
537
|
@context.io.prompt
|
543
538
|
end
|
544
539
|
|
545
|
-
@scanner.set_input
|
540
|
+
@scanner.set_input do
|
546
541
|
signal_status(:IN_INPUT) do
|
547
542
|
if l = @context.io.gets
|
548
543
|
print l if @context.verbose?
|
@@ -560,12 +555,11 @@ module IRB
|
|
560
555
|
end
|
561
556
|
end
|
562
557
|
|
563
|
-
@scanner.
|
558
|
+
@scanner.configure_io(@context.io)
|
564
559
|
|
565
560
|
@scanner.each_top_level_statement do |line, line_no|
|
566
561
|
signal_status(:IN_EVAL) do
|
567
562
|
begin
|
568
|
-
line.untaint if RUBY_VERSION < '2.7'
|
569
563
|
if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty?
|
570
564
|
IRB.set_measure_callback
|
571
565
|
end
|
@@ -897,11 +891,6 @@ module IRB
|
|
897
891
|
ensure
|
898
892
|
$VERBOSE = verbose
|
899
893
|
end
|
900
|
-
|
901
|
-
ATTR_TTY = "\e[%sm"
|
902
|
-
def ATTR_TTY.[](*a) self % a.join(";"); end
|
903
|
-
ATTR_PLAIN = ""
|
904
|
-
def ATTR_PLAIN.[](*) self; end
|
905
894
|
end
|
906
895
|
|
907
896
|
def @CONF.inspect
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: irb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aycabta
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-06-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: reline
|
@@ -66,6 +66,7 @@ files:
|
|
66
66
|
- lib/irb/cmd/nop.rb
|
67
67
|
- lib/irb/cmd/pushws.rb
|
68
68
|
- lib/irb/cmd/show_cmds.rb
|
69
|
+
- lib/irb/cmd/show_doc.rb
|
69
70
|
- lib/irb/cmd/show_source.rb
|
70
71
|
- lib/irb/cmd/step.rb
|
71
72
|
- lib/irb/cmd/subirb.rb
|
@@ -91,11 +92,9 @@ files:
|
|
91
92
|
- lib/irb/inspector.rb
|
92
93
|
- lib/irb/lc/error.rb
|
93
94
|
- lib/irb/lc/help-message
|
94
|
-
- lib/irb/lc/ja/encoding_aliases.rb
|
95
95
|
- lib/irb/lc/ja/error.rb
|
96
96
|
- lib/irb/lc/ja/help-message
|
97
97
|
- lib/irb/locale.rb
|
98
|
-
- lib/irb/magic-file.rb
|
99
98
|
- lib/irb/notifier.rb
|
100
99
|
- lib/irb/output-method.rb
|
101
100
|
- lib/irb/ruby-lex.rb
|
@@ -123,14 +122,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
122
|
requirements:
|
124
123
|
- - ">="
|
125
124
|
- !ruby/object:Gem::Version
|
126
|
-
version: '2.
|
125
|
+
version: '2.7'
|
127
126
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
127
|
requirements:
|
129
128
|
- - ">="
|
130
129
|
- !ruby/object:Gem::Version
|
131
130
|
version: '0'
|
132
131
|
requirements: []
|
133
|
-
rubygems_version: 3.
|
132
|
+
rubygems_version: 3.5.0.dev
|
134
133
|
signing_key:
|
135
134
|
specification_version: 4
|
136
135
|
summary: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).
|
data/lib/irb/magic-file.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: false
|
2
|
-
module IRB
|
3
|
-
class << (MagicFile = Object.new)
|
4
|
-
# see parser_magic_comment in parse.y
|
5
|
-
ENCODING_SPEC_RE = %r"coding\s*[=:]\s*([[:alnum:]\-_]+)"
|
6
|
-
|
7
|
-
def open(path)
|
8
|
-
io = File.open(path, 'rb')
|
9
|
-
line = io.gets
|
10
|
-
line = io.gets if line[0,2] == "#!"
|
11
|
-
encoding = detect_encoding(line)
|
12
|
-
internal_encoding = encoding
|
13
|
-
encoding ||= IRB.default_src_encoding
|
14
|
-
io.rewind
|
15
|
-
io.set_encoding(encoding, internal_encoding)
|
16
|
-
|
17
|
-
if block_given?
|
18
|
-
begin
|
19
|
-
return (yield io)
|
20
|
-
ensure
|
21
|
-
io.close
|
22
|
-
end
|
23
|
-
else
|
24
|
-
return io
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
def detect_encoding(line)
|
30
|
-
return unless line[0] == ?#
|
31
|
-
line = line[1..-1]
|
32
|
-
line = $1 if line[/-\*-\s*(.*?)\s*-*-$/]
|
33
|
-
return nil unless ENCODING_SPEC_RE =~ line
|
34
|
-
encoding = $1
|
35
|
-
return encoding.sub(/-(?:mac|dos|unix)/i, '')
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|