irb 1.6.3 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/irb.svg)](https://badge.fury.io/rb/irb)
|
4
|
+
[![build](https://github.com/ruby/irb/actions/workflows/test.yml/badge.svg)](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
|