irb 1.3.4 → 1.3.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +7 -0
- data/irb.gemspec +1 -46
- data/lib/irb.rb +16 -6
- data/lib/irb/cmd/ls.rb +83 -0
- data/lib/irb/cmd/nop.rb +10 -4
- data/lib/irb/cmd/show_source.rb +86 -0
- data/lib/irb/cmd/whereami.rb +20 -0
- data/lib/irb/color.rb +4 -1
- data/lib/irb/color_printer.rb +9 -0
- data/lib/irb/completion.rb +73 -3
- data/lib/irb/ext/save-history.rb +15 -5
- data/lib/irb/extend-command.rb +21 -4
- data/lib/irb/input-method.rb +1 -0
- data/lib/irb/lc/help-message +6 -6
- data/lib/irb/ruby-lex.rb +73 -13
- data/lib/irb/version.rb +2 -2
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7a7034e210074f2c31db1369ffe0d5203cd7d2d35a1b9df36cbabfe6d52109e
|
4
|
+
data.tar.gz: c22c2ea2a1fb878c0b96d194c8b5af832c07d4b53173ebec07cfcadb04ac4d33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9017a414d09dc360a6846aa23917133f57145bdc529642931912c92c1ce675c5312705a105a5098e8cec351b6997da379a745097238d98f1e18f976ed9da4594
|
7
|
+
data.tar.gz: 67f3e78b20d4ea3881d6bea7deb8da4a2c9066029ffc19de9ed78b906cfae50f43e93da8b5ab306ac44b43f2555d0b3a65e3678ef10ba00f0e87221bb7f7a22d
|
data/Rakefile
CHANGED
@@ -7,4 +7,11 @@ Rake::TestTask.new(:test) do |t|
|
|
7
7
|
t.test_files = FileList["test/**/test_*.rb"]
|
8
8
|
end
|
9
9
|
|
10
|
+
Rake::TestTask.new(:test_yamatanooroti) do |t|
|
11
|
+
t.libs << 'test'
|
12
|
+
t.libs << 'lib'
|
13
|
+
#t.loader = :direct
|
14
|
+
t.pattern = 'test/irb/yamatanooroti/test_*.rb'
|
15
|
+
end
|
16
|
+
|
10
17
|
task :default => :test
|
data/irb.gemspec
CHANGED
@@ -28,53 +28,8 @@ Gem::Specification.new do |spec|
|
|
28
28
|
"doc/irb/irb.rd.ja",
|
29
29
|
"exe/irb",
|
30
30
|
"irb.gemspec",
|
31
|
-
"lib/irb.rb",
|
32
|
-
"lib/irb/cmd/chws.rb",
|
33
|
-
"lib/irb/cmd/fork.rb",
|
34
|
-
"lib/irb/cmd/help.rb",
|
35
|
-
"lib/irb/cmd/info.rb",
|
36
|
-
"lib/irb/cmd/load.rb",
|
37
|
-
"lib/irb/cmd/measure.rb",
|
38
|
-
"lib/irb/cmd/nop.rb",
|
39
|
-
"lib/irb/cmd/pushws.rb",
|
40
|
-
"lib/irb/cmd/subirb.rb",
|
41
|
-
"lib/irb/color.rb",
|
42
|
-
"lib/irb/color_printer.rb",
|
43
|
-
"lib/irb/completion.rb",
|
44
|
-
"lib/irb/context.rb",
|
45
|
-
"lib/irb/easter-egg.rb",
|
46
|
-
"lib/irb/ext/change-ws.rb",
|
47
|
-
"lib/irb/ext/history.rb",
|
48
|
-
"lib/irb/ext/loader.rb",
|
49
|
-
"lib/irb/ext/multi-irb.rb",
|
50
|
-
"lib/irb/ext/save-history.rb",
|
51
|
-
"lib/irb/ext/tracer.rb",
|
52
|
-
"lib/irb/ext/use-loader.rb",
|
53
|
-
"lib/irb/ext/workspaces.rb",
|
54
|
-
"lib/irb/extend-command.rb",
|
55
|
-
"lib/irb/frame.rb",
|
56
|
-
"lib/irb/help.rb",
|
57
|
-
"lib/irb/init.rb",
|
58
|
-
"lib/irb/input-method.rb",
|
59
|
-
"lib/irb/inspector.rb",
|
60
|
-
"lib/irb/lc/error.rb",
|
61
|
-
"lib/irb/lc/help-message",
|
62
|
-
"lib/irb/lc/ja/encoding_aliases.rb",
|
63
|
-
"lib/irb/lc/ja/error.rb",
|
64
|
-
"lib/irb/lc/ja/help-message",
|
65
|
-
"lib/irb/locale.rb",
|
66
|
-
"lib/irb/magic-file.rb",
|
67
|
-
"lib/irb/notifier.rb",
|
68
|
-
"lib/irb/output-method.rb",
|
69
|
-
"lib/irb/ruby-lex.rb",
|
70
|
-
"lib/irb/ruby_logo.aa",
|
71
|
-
"lib/irb/src_encoding.rb",
|
72
|
-
"lib/irb/version.rb",
|
73
|
-
"lib/irb/workspace.rb",
|
74
|
-
"lib/irb/ws-for-case-2.rb",
|
75
|
-
"lib/irb/xmp.rb",
|
76
31
|
"man/irb.1",
|
77
|
-
]
|
32
|
+
] + Dir.glob("lib/**/*")
|
78
33
|
spec.bindir = "exe"
|
79
34
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
80
35
|
spec.require_paths = ["lib"]
|
data/lib/irb.rb
CHANGED
@@ -60,7 +60,11 @@ require_relative "irb/easter-egg"
|
|
60
60
|
# -E enc Same as `ruby -E`
|
61
61
|
# -w Same as `ruby -w`
|
62
62
|
# -W[level=2] Same as `ruby -W`
|
63
|
-
# --
|
63
|
+
# --context-mode n Set n[0-4] to method to create Binding Object,
|
64
|
+
# when new workspace was created
|
65
|
+
# --echo Show result(default)
|
66
|
+
# --noecho Don't show result
|
67
|
+
# --inspect Use `inspect' for output
|
64
68
|
# --noinspect Don't use inspect for output
|
65
69
|
# --multiline Use multiline editor module
|
66
70
|
# --nomultiline Don't use multiline editor module
|
@@ -68,19 +72,24 @@ require_relative "irb/easter-egg"
|
|
68
72
|
# --nosingleline Don't use singleline editor module
|
69
73
|
# --colorize Use colorization
|
70
74
|
# --nocolorize Don't use colorization
|
71
|
-
# --prompt prompt-mode
|
72
|
-
# --prompt-mode prompt-mode
|
75
|
+
# --prompt prompt-mode/--prompt-mode prompt-mode
|
73
76
|
# Switch prompt mode. Pre-defined prompt modes are
|
74
77
|
# `default', `simple', `xmp' and `inf-ruby'
|
75
78
|
# --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
|
76
79
|
# Suppresses --multiline and --singleline.
|
77
|
-
# --simple-prompt
|
80
|
+
# --sample-book-mode/--simple-prompt
|
81
|
+
# Simple prompt mode
|
78
82
|
# --noprompt No prompt mode
|
83
|
+
# --single-irb Share self with sub-irb.
|
79
84
|
# --tracer Display trace for each execution of commands.
|
80
85
|
# --back-trace-limit n
|
81
86
|
# Display backtrace top n and tail n. The default
|
82
87
|
# value is 16.
|
83
|
-
#
|
88
|
+
# --verbose Show details
|
89
|
+
# --noverbose Don't show details
|
90
|
+
# -v, --version Print the version of irb
|
91
|
+
# -h, --help Print help
|
92
|
+
# -- Separate options of irb from the list of command-line args
|
84
93
|
#
|
85
94
|
# == Configuration
|
86
95
|
#
|
@@ -463,7 +472,7 @@ module IRB
|
|
463
472
|
conf[:IRB_RC].call(context) if conf[:IRB_RC]
|
464
473
|
conf[:MAIN_CONTEXT] = context
|
465
474
|
|
466
|
-
trap("SIGINT") do
|
475
|
+
prev_trap = trap("SIGINT") do
|
467
476
|
signal_handle
|
468
477
|
end
|
469
478
|
|
@@ -472,6 +481,7 @@ module IRB
|
|
472
481
|
eval_input
|
473
482
|
end
|
474
483
|
ensure
|
484
|
+
trap("SIGINT", prev_trap)
|
475
485
|
conf[:AT_EXIT].each{|hook| hook.call}
|
476
486
|
end
|
477
487
|
end
|
data/lib/irb/cmd/ls.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "reline"
|
4
|
+
require_relative "nop"
|
5
|
+
require_relative "../color"
|
6
|
+
|
7
|
+
# :stopdoc:
|
8
|
+
module IRB
|
9
|
+
module ExtendCommand
|
10
|
+
class Ls < Nop
|
11
|
+
def execute(*arg, grep: nil)
|
12
|
+
o = Output.new(grep: grep)
|
13
|
+
|
14
|
+
obj = arg.empty? ? irb_context.workspace.main : arg.first
|
15
|
+
locals = arg.empty? ? irb_context.workspace.binding.local_variables : []
|
16
|
+
klass = (obj.class == Class || obj.class == Module ? obj : obj.class)
|
17
|
+
|
18
|
+
o.dump("constants", obj.constants) if obj.respond_to?(:constants)
|
19
|
+
o.dump("#{klass}.methods", obj.singleton_methods(false))
|
20
|
+
o.dump("#{klass}#methods", klass.public_instance_methods(false))
|
21
|
+
o.dump("instance variables", obj.instance_variables)
|
22
|
+
o.dump("class variables", klass.class_variables)
|
23
|
+
o.dump("locals", locals)
|
24
|
+
end
|
25
|
+
|
26
|
+
class Output
|
27
|
+
MARGIN = " "
|
28
|
+
|
29
|
+
def initialize(grep: nil)
|
30
|
+
@grep = grep
|
31
|
+
@line_width = screen_width - MARGIN.length # right padding
|
32
|
+
end
|
33
|
+
|
34
|
+
def dump(name, strs)
|
35
|
+
strs = strs.grep(@grep) if @grep
|
36
|
+
strs = strs.sort
|
37
|
+
return if strs.empty?
|
38
|
+
|
39
|
+
# Attempt a single line
|
40
|
+
print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
|
41
|
+
if fits_on_line?(strs, cols: strs.size, offset: "#{name}: ".length)
|
42
|
+
puts strs.join(MARGIN)
|
43
|
+
return
|
44
|
+
end
|
45
|
+
puts
|
46
|
+
|
47
|
+
# Dump with the largest # of columns that fits on a line
|
48
|
+
cols = strs.size
|
49
|
+
until fits_on_line?(strs, cols: cols, offset: MARGIN.length) || cols == 1
|
50
|
+
cols -= 1
|
51
|
+
end
|
52
|
+
widths = col_widths(strs, cols: cols)
|
53
|
+
strs.each_slice(cols) do |ss|
|
54
|
+
puts ss.map.with_index { |s, i| "#{MARGIN}%-#{widths[i]}s" % s }.join
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def fits_on_line?(strs, cols:, offset: 0)
|
61
|
+
width = col_widths(strs, cols: cols).sum + MARGIN.length * (cols - 1)
|
62
|
+
width <= @line_width - offset
|
63
|
+
end
|
64
|
+
|
65
|
+
def col_widths(strs, cols:)
|
66
|
+
cols.times.map do |col|
|
67
|
+
(col...strs.size).step(cols).map do |i|
|
68
|
+
strs[i].length
|
69
|
+
end.max
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def screen_width
|
74
|
+
Reline.get_screen_size.last
|
75
|
+
rescue Errno::EINVAL # in `winsize': Invalid argument - <STDIN>
|
76
|
+
80
|
77
|
+
end
|
78
|
+
end
|
79
|
+
private_constant :Output
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
# :startdoc:
|
data/lib/irb/cmd/nop.rb
CHANGED
@@ -14,10 +14,16 @@ module IRB
|
|
14
14
|
module ExtendCommand
|
15
15
|
class Nop
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
|
18
|
+
def self.execute(conf, *opts, **kwargs, &block)
|
19
|
+
command = new(conf)
|
20
|
+
command.execute(*opts, **kwargs, &block)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
def self.execute(conf, *opts, &block)
|
24
|
+
command = new(conf)
|
25
|
+
command.execute(*opts, &block)
|
26
|
+
end
|
21
27
|
end
|
22
28
|
|
23
29
|
def initialize(conf)
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "nop"
|
4
|
+
require_relative "../color"
|
5
|
+
require_relative "../ruby-lex"
|
6
|
+
|
7
|
+
# :stopdoc:
|
8
|
+
module IRB
|
9
|
+
module ExtendCommand
|
10
|
+
class ShowSource < Nop
|
11
|
+
def execute(str = nil)
|
12
|
+
unless str.is_a?(String)
|
13
|
+
puts "Error: Expected a string but got #{str.inspect}"
|
14
|
+
return
|
15
|
+
end
|
16
|
+
source = find_source(str)
|
17
|
+
if source && File.exist?(source.file)
|
18
|
+
show_source(source)
|
19
|
+
else
|
20
|
+
puts "Error: Couldn't locate a definition for #{str}"
|
21
|
+
end
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# @param [IRB::ExtendCommand::ShowSource::Source] source
|
28
|
+
def show_source(source)
|
29
|
+
puts
|
30
|
+
puts "#{bold("From")}: #{source.file}:#{source.first_line}"
|
31
|
+
puts
|
32
|
+
code = IRB::Color.colorize_code(File.read(source.file))
|
33
|
+
puts code.lines[(source.first_line - 1)...source.last_line].join
|
34
|
+
puts
|
35
|
+
end
|
36
|
+
|
37
|
+
def find_source(str)
|
38
|
+
case str
|
39
|
+
when /\A[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name
|
40
|
+
eval(str, irb_context.workspace.binding) # trigger autoload
|
41
|
+
base = irb_context.workspace.binding.receiver.yield_self { |r| r.is_a?(Module) ? r : Object }
|
42
|
+
file, line = base.const_source_location(str) if base.respond_to?(:const_source_location) # Ruby 2.7+
|
43
|
+
when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
|
44
|
+
owner = eval(Regexp.last_match[:owner], irb_context.workspace.binding)
|
45
|
+
method = Regexp.last_match[:method]
|
46
|
+
if owner.respond_to?(:instance_method) && owner.instance_methods.include?(method.to_sym)
|
47
|
+
file, line = owner.instance_method(method).source_location
|
48
|
+
end
|
49
|
+
when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method
|
50
|
+
receiver = eval(Regexp.last_match[:receiver] || 'self', irb_context.workspace.binding)
|
51
|
+
method = Regexp.last_match[:method]
|
52
|
+
file, line = receiver.method(method).source_location if receiver.respond_to?(method)
|
53
|
+
end
|
54
|
+
if file && line
|
55
|
+
Source.new(file: file, first_line: line, last_line: find_end(file, line))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def find_end(file, first_line)
|
60
|
+
return first_line unless File.exist?(file)
|
61
|
+
lex = RubyLex.new
|
62
|
+
code = +""
|
63
|
+
File.read(file).lines[(first_line - 1)..-1].each_with_index do |line, i|
|
64
|
+
_ltype, _indent, continue, code_block_open = lex.check_state(code << line)
|
65
|
+
if !continue && !code_block_open
|
66
|
+
return first_line + i
|
67
|
+
end
|
68
|
+
end
|
69
|
+
first_line
|
70
|
+
end
|
71
|
+
|
72
|
+
def bold(str)
|
73
|
+
Color.colorize(str, [:BOLD])
|
74
|
+
end
|
75
|
+
|
76
|
+
Source = Struct.new(
|
77
|
+
:file, # @param [String] - file name
|
78
|
+
:first_line, # @param [String] - first line
|
79
|
+
:last_line, # @param [String] - last line
|
80
|
+
keyword_init: true,
|
81
|
+
)
|
82
|
+
private_constant :Source
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
# :startdoc:
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "nop"
|
4
|
+
|
5
|
+
# :stopdoc:
|
6
|
+
module IRB
|
7
|
+
module ExtendCommand
|
8
|
+
class Whereami < Nop
|
9
|
+
def execute(*)
|
10
|
+
code = irb_context.workspace.code_around_binding
|
11
|
+
if code
|
12
|
+
puts code
|
13
|
+
else
|
14
|
+
puts "The current context doesn't have code."
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
# :startdoc:
|
data/lib/irb/color.rb
CHANGED
@@ -64,6 +64,7 @@ module IRB # :nodoc:
|
|
64
64
|
on_alias_error: [[RED, REVERSE], ALL],
|
65
65
|
on_class_name_error:[[RED, REVERSE], ALL],
|
66
66
|
on_param_error: [[RED, REVERSE], ALL],
|
67
|
+
on___end__: [[GREEN], ALL],
|
67
68
|
}
|
68
69
|
rescue NameError
|
69
70
|
# Give up highlighting Ripper-incompatible older Ruby
|
@@ -120,6 +121,7 @@ module IRB # :nodoc:
|
|
120
121
|
symbol_state = SymbolState.new
|
121
122
|
colored = +''
|
122
123
|
length = 0
|
124
|
+
end_seen = false
|
123
125
|
|
124
126
|
scan(code, allow_last_error: !complete) do |token, str, expr|
|
125
127
|
# IRB::ColorPrinter skips colorizing fragments with any invalid token
|
@@ -138,10 +140,11 @@ module IRB # :nodoc:
|
|
138
140
|
end
|
139
141
|
end
|
140
142
|
length += str.bytesize
|
143
|
+
end_seen = true if token == :on___end__
|
141
144
|
end
|
142
145
|
|
143
146
|
# give up colorizing incomplete Ripper tokens
|
144
|
-
|
147
|
+
unless end_seen or length == code.bytesize
|
145
148
|
return Reline::Unicode.escape_for_print(code)
|
146
149
|
end
|
147
150
|
|
data/lib/irb/color_printer.rb
CHANGED
@@ -21,6 +21,15 @@ module IRB
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
def pp(obj)
|
25
|
+
if obj.is_a?(String)
|
26
|
+
# Avoid calling Ruby 2.4+ String#pretty_print that splits a string by "\n"
|
27
|
+
text(obj.inspect)
|
28
|
+
else
|
29
|
+
super
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
24
33
|
def text(str, width = nil)
|
25
34
|
unless str.is_a?(String)
|
26
35
|
str = str.inspect
|
data/lib/irb/completion.rb
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
# From Original Idea of shugo@ruby-lang.org
|
8
8
|
#
|
9
9
|
|
10
|
-
|
10
|
+
require_relative 'ruby-lex'
|
11
11
|
|
12
12
|
module IRB
|
13
13
|
module InputCompletor # :nodoc:
|
@@ -38,8 +38,69 @@ module IRB
|
|
38
38
|
|
39
39
|
BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
|
40
40
|
|
41
|
-
|
42
|
-
|
41
|
+
def self.retrieve_files_to_require_from_load_path
|
42
|
+
@@files_from_load_path ||= $LOAD_PATH.flat_map { |path|
|
43
|
+
begin
|
44
|
+
Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: path)
|
45
|
+
rescue Errno::ENOENT
|
46
|
+
[]
|
47
|
+
end
|
48
|
+
}.uniq.map { |path|
|
49
|
+
path.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '')
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.retrieve_files_to_require_relative_from_current_dir
|
54
|
+
@@files_from_current_dir ||= Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: '.').map { |path|
|
55
|
+
path.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '')
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
CompletionRequireProc = lambda { |target, preposing = nil, postposing = nil|
|
60
|
+
if target =~ /\A(['"])([^'"]+)\Z/
|
61
|
+
quote = $1
|
62
|
+
actual_target = $2
|
63
|
+
else
|
64
|
+
return nil # It's not String literal
|
65
|
+
end
|
66
|
+
tokens = RubyLex.ripper_lex_without_warning(preposing.gsub(/\s*\z/, ''))
|
67
|
+
tok = nil
|
68
|
+
tokens.reverse_each do |t|
|
69
|
+
unless [:on_lparen, :on_sp, :on_ignored_sp, :on_nl, :on_ignored_nl, :on_comment].include?(t.event)
|
70
|
+
tok = t
|
71
|
+
break
|
72
|
+
end
|
73
|
+
end
|
74
|
+
result = []
|
75
|
+
if tok && tok.event == :on_ident && tok.state == Ripper::EXPR_CMDARG
|
76
|
+
case tok.tok
|
77
|
+
when 'require'
|
78
|
+
result = retrieve_files_to_require_from_load_path.select { |path|
|
79
|
+
path.start_with?(actual_target)
|
80
|
+
}.map { |path|
|
81
|
+
quote + path
|
82
|
+
}
|
83
|
+
when 'require_relative'
|
84
|
+
result = retrieve_files_to_require_relative_from_current_dir.select { |path|
|
85
|
+
path.start_with?(actual_target)
|
86
|
+
}.map { |path|
|
87
|
+
quote + path
|
88
|
+
}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
result
|
92
|
+
}
|
93
|
+
|
94
|
+
CompletionProc = lambda { |target, preposing = nil, postposing = nil|
|
95
|
+
if preposing && postposing
|
96
|
+
result = CompletionRequireProc.(target, preposing, postposing)
|
97
|
+
unless result
|
98
|
+
result = retrieve_completion_data(target).compact.map{ |i| i.encode(Encoding.default_external) }
|
99
|
+
end
|
100
|
+
result
|
101
|
+
else
|
102
|
+
retrieve_completion_data(target).compact.map{ |i| i.encode(Encoding.default_external) }
|
103
|
+
end
|
43
104
|
}
|
44
105
|
|
45
106
|
def self.retrieve_completion_data(input, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding, doc_namespace: false)
|
@@ -266,13 +327,22 @@ module IRB
|
|
266
327
|
end
|
267
328
|
|
268
329
|
PerfectMatchedProc = ->(matched, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding) {
|
330
|
+
begin
|
331
|
+
require 'rdoc'
|
332
|
+
rescue LoadError
|
333
|
+
return
|
334
|
+
end
|
335
|
+
|
269
336
|
RDocRIDriver ||= RDoc::RI::Driver.new
|
337
|
+
|
270
338
|
if matched =~ /\A(?:::)?RubyVM/ and not ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
|
271
339
|
IRB.__send__(:easter_egg)
|
272
340
|
return
|
273
341
|
end
|
342
|
+
|
274
343
|
namespace = retrieve_completion_data(matched, bind: bind, doc_namespace: true)
|
275
344
|
return unless namespace
|
345
|
+
|
276
346
|
if namespace.is_a?(Array)
|
277
347
|
out = RDoc::Markup::Document.new
|
278
348
|
namespace.each do |m|
|
data/lib/irb/ext/save-history.rb
CHANGED
@@ -81,6 +81,8 @@ module IRB
|
|
81
81
|
end
|
82
82
|
}
|
83
83
|
end
|
84
|
+
@loaded_history_lines = history.size
|
85
|
+
@loaded_history_mtime = File.mtime(history_file)
|
84
86
|
end
|
85
87
|
end
|
86
88
|
|
@@ -105,12 +107,20 @@ module IRB
|
|
105
107
|
raise
|
106
108
|
end
|
107
109
|
|
108
|
-
|
110
|
+
if File.exist?(history_file) && @loaded_history_mtime &&
|
111
|
+
File.mtime(history_file) != @loaded_history_mtime
|
112
|
+
history = history[@loaded_history_lines..-1]
|
113
|
+
append_history = true
|
114
|
+
end
|
115
|
+
|
116
|
+
open(history_file, "#{append_history ? 'a' : 'w'}:#{IRB.conf[:LC_MESSAGES].encoding}", 0600) do |f|
|
109
117
|
hist = history.map{ |l| l.split("\n").join("\\\n") }
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
118
|
+
unless append_history
|
119
|
+
begin
|
120
|
+
hist = hist.last(num) if hist.size > num and num > 0
|
121
|
+
rescue RangeError # bignum too big to convert into `long'
|
122
|
+
# Do nothing because the bignum should be treated as inifinity
|
123
|
+
end
|
114
124
|
end
|
115
125
|
f.puts(hist)
|
116
126
|
end
|
data/lib/irb/extend-command.rb
CHANGED
@@ -126,7 +126,23 @@ module IRB # :nodoc:
|
|
126
126
|
],
|
127
127
|
|
128
128
|
[
|
129
|
-
:
|
129
|
+
:irb_ls, :Ls, "irb/cmd/ls",
|
130
|
+
[:ls, NO_OVERRIDE],
|
131
|
+
],
|
132
|
+
|
133
|
+
[
|
134
|
+
:irb_measure, :Measure, "irb/cmd/measure",
|
135
|
+
[:measure, NO_OVERRIDE],
|
136
|
+
],
|
137
|
+
|
138
|
+
[
|
139
|
+
:irb_show_source, :ShowSource, "irb/cmd/show_source",
|
140
|
+
[:show_source, NO_OVERRIDE],
|
141
|
+
],
|
142
|
+
|
143
|
+
[
|
144
|
+
:irb_whereami, :Whereami, "irb/cmd/whereami",
|
145
|
+
[:whereami, NO_OVERRIDE],
|
130
146
|
],
|
131
147
|
|
132
148
|
]
|
@@ -168,12 +184,13 @@ module IRB # :nodoc:
|
|
168
184
|
end
|
169
185
|
|
170
186
|
if load_file
|
187
|
+
kwargs = ", **kwargs" if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
|
171
188
|
line = __LINE__; eval %[
|
172
|
-
def #{cmd_name}(*opts, &b)
|
189
|
+
def #{cmd_name}(*opts#{kwargs}, &b)
|
173
190
|
require "#{load_file}"
|
174
191
|
arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity
|
175
192
|
args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s }
|
176
|
-
args << "*opts" if arity < 0
|
193
|
+
args << "*opts#{kwargs}" if arity < 0
|
177
194
|
args << "&block"
|
178
195
|
args = args.join(", ")
|
179
196
|
line = __LINE__; eval %[
|
@@ -184,7 +201,7 @@ module IRB # :nodoc:
|
|
184
201
|
end
|
185
202
|
end
|
186
203
|
], nil, __FILE__, line
|
187
|
-
__send__ :#{cmd_name}_, *opts, &b
|
204
|
+
__send__ :#{cmd_name}_, *opts#{kwargs}, &b
|
188
205
|
end
|
189
206
|
], nil, __FILE__, line
|
190
207
|
else
|
data/lib/irb/input-method.rb
CHANGED
@@ -280,6 +280,7 @@ module IRB
|
|
280
280
|
Reline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
|
281
281
|
end
|
282
282
|
Reline.completion_append_character = nil
|
283
|
+
Reline.completer_quote_characters = ''
|
283
284
|
Reline.completion_proc = IRB::InputCompletor::CompletionProc
|
284
285
|
Reline.output_modifier_proc =
|
285
286
|
if IRB.conf[:USE_COLORIZE]
|
data/lib/irb/lc/help-message
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
#
|
12
12
|
Usage: irb.rb [options] [programfile] [arguments]
|
13
|
-
-f
|
13
|
+
-f Suppress read of ~/.irbrc
|
14
14
|
-d Set $DEBUG to true (same as `ruby -d')
|
15
15
|
-r load-module Same as `ruby -r'
|
16
16
|
-I path Specify $LOAD_PATH directory
|
@@ -18,7 +18,7 @@ Usage: irb.rb [options] [programfile] [arguments]
|
|
18
18
|
-E enc Same as `ruby -E`
|
19
19
|
-w Same as `ruby -w`
|
20
20
|
-W[level=2] Same as `ruby -W`
|
21
|
-
--context-mode n Set n[0-
|
21
|
+
--context-mode n Set n[0-4] to method to create Binding Object,
|
22
22
|
when new workspace was created
|
23
23
|
--echo Show result(default)
|
24
24
|
--noecho Don't show result
|
@@ -31,8 +31,8 @@ Usage: irb.rb [options] [programfile] [arguments]
|
|
31
31
|
--colorize Use colorization
|
32
32
|
--nocolorize Don't use colorization
|
33
33
|
--prompt prompt-mode/--prompt-mode prompt-mode
|
34
|
-
|
35
|
-
|
34
|
+
Switch prompt mode. Pre-defined prompt modes are
|
35
|
+
`default', `simple', `xmp' and `inf-ruby'
|
36
36
|
--inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
|
37
37
|
Suppresses --multiline and --singleline.
|
38
38
|
--sample-book-mode/--simple-prompt
|
@@ -41,8 +41,8 @@ Usage: irb.rb [options] [programfile] [arguments]
|
|
41
41
|
--single-irb Share self with sub-irb.
|
42
42
|
--tracer Display trace for each execution of commands.
|
43
43
|
--back-trace-limit n
|
44
|
-
|
45
|
-
|
44
|
+
Display backtrace top n and tail n. The default
|
45
|
+
value is 16.
|
46
46
|
--verbose Show details
|
47
47
|
--noverbose Don't show details
|
48
48
|
-v, --version Print the version of irb
|
data/lib/irb/ruby-lex.rb
CHANGED
@@ -47,12 +47,26 @@ class RubyLex
|
|
47
47
|
@io = io
|
48
48
|
if @io.respond_to?(:check_termination)
|
49
49
|
@io.check_termination do |code|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
if Reline::IOGate.in_pasting?
|
51
|
+
lex = RubyLex.new
|
52
|
+
rest = lex.check_termination_in_prev_line(code)
|
53
|
+
if rest
|
54
|
+
Reline.delete_text
|
55
|
+
rest.bytes.reverse_each do |c|
|
56
|
+
Reline.ungetc(c)
|
57
|
+
end
|
58
|
+
true
|
59
|
+
else
|
60
|
+
false
|
61
|
+
end
|
54
62
|
else
|
55
|
-
|
63
|
+
code.gsub!(/\s*\z/, '').concat("\n")
|
64
|
+
ltype, indent, continue, code_block_open = check_state(code)
|
65
|
+
if ltype or indent > 0 or continue or code_block_open
|
66
|
+
false
|
67
|
+
else
|
68
|
+
true
|
69
|
+
end
|
56
70
|
end
|
57
71
|
end
|
58
72
|
end
|
@@ -60,7 +74,7 @@ class RubyLex
|
|
60
74
|
@io.dynamic_prompt do |lines|
|
61
75
|
lines << '' if lines.empty?
|
62
76
|
result = []
|
63
|
-
tokens = ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join)
|
77
|
+
tokens = self.class.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join)
|
64
78
|
code = String.new
|
65
79
|
partial_tokens = []
|
66
80
|
unprocessed_tokens = []
|
@@ -115,10 +129,10 @@ class RubyLex
|
|
115
129
|
:on_param_error
|
116
130
|
]
|
117
131
|
|
118
|
-
def ripper_lex_without_warning(code)
|
132
|
+
def self.ripper_lex_without_warning(code)
|
119
133
|
verbose, $VERBOSE = $VERBOSE, nil
|
120
134
|
tokens = nil
|
121
|
-
|
135
|
+
compile_with_errors_suppressed(code) do |inner_code, line_no|
|
122
136
|
lexer = Ripper::Lexer.new(inner_code, '-', line_no)
|
123
137
|
if lexer.respond_to?(:scan) # Ruby 2.7+
|
124
138
|
tokens = []
|
@@ -168,7 +182,7 @@ class RubyLex
|
|
168
182
|
if @io.respond_to?(:auto_indent) and context.auto_indent_mode
|
169
183
|
@io.auto_indent do |lines, line_index, byte_pointer, is_newline|
|
170
184
|
if is_newline
|
171
|
-
@tokens = ripper_lex_without_warning(lines[0..line_index].join("\n"))
|
185
|
+
@tokens = self.class.ripper_lex_without_warning(lines[0..line_index].join("\n"))
|
172
186
|
prev_spaces = find_prev_spaces(line_index)
|
173
187
|
depth_difference = check_newline_depth_difference
|
174
188
|
depth_difference = 0 if depth_difference < 0
|
@@ -177,7 +191,7 @@ class RubyLex
|
|
177
191
|
code = line_index.zero? ? '' : lines[0..(line_index - 1)].map{ |l| l + "\n" }.join
|
178
192
|
last_line = lines[line_index]&.byteslice(0, byte_pointer)
|
179
193
|
code += last_line if last_line
|
180
|
-
@tokens = ripper_lex_without_warning(code)
|
194
|
+
@tokens = self.class.ripper_lex_without_warning(code)
|
181
195
|
corresponding_token_depth = check_corresponding_token_depth
|
182
196
|
if corresponding_token_depth
|
183
197
|
corresponding_token_depth
|
@@ -190,7 +204,7 @@ class RubyLex
|
|
190
204
|
end
|
191
205
|
|
192
206
|
def check_state(code, tokens = nil)
|
193
|
-
tokens = ripper_lex_without_warning(code) unless tokens
|
207
|
+
tokens = self.class.ripper_lex_without_warning(code) unless tokens
|
194
208
|
ltype = process_literal_type(tokens)
|
195
209
|
indent = process_nesting_level(tokens)
|
196
210
|
continue = process_continue(tokens)
|
@@ -256,7 +270,7 @@ class RubyLex
|
|
256
270
|
end
|
257
271
|
code = @line + (line.nil? ? '' : line)
|
258
272
|
code.gsub!(/\s*\z/, '').concat("\n")
|
259
|
-
@tokens = ripper_lex_without_warning(code)
|
273
|
+
@tokens = self.class.ripper_lex_without_warning(code)
|
260
274
|
@continue = process_continue
|
261
275
|
@code_block_open = check_code_block(code)
|
262
276
|
@indent = process_nesting_level
|
@@ -277,8 +291,9 @@ class RubyLex
|
|
277
291
|
return true
|
278
292
|
elsif tokens.size >= 1 and tokens[-1][1] == :on_heredoc_end # "EOH\n"
|
279
293
|
return false
|
280
|
-
elsif tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and tokens[-2][3].anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME)
|
294
|
+
elsif tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and tokens[-2][3].anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME) and tokens[-2][2] !~ /\A\.\.\.?\z/
|
281
295
|
# end of literal except for regexp
|
296
|
+
# endless range at end of line is not a continue
|
282
297
|
return true
|
283
298
|
end
|
284
299
|
false
|
@@ -738,5 +753,50 @@ class RubyLex
|
|
738
753
|
nil
|
739
754
|
end
|
740
755
|
end
|
756
|
+
|
757
|
+
def check_termination_in_prev_line(code)
|
758
|
+
tokens = self.class.ripper_lex_without_warning(code)
|
759
|
+
past_first_newline = false
|
760
|
+
index = tokens.rindex do |t|
|
761
|
+
# traverse first token before last line
|
762
|
+
if past_first_newline
|
763
|
+
if t.tok.include?("\n")
|
764
|
+
true
|
765
|
+
end
|
766
|
+
elsif t.tok.include?("\n")
|
767
|
+
past_first_newline = true
|
768
|
+
false
|
769
|
+
else
|
770
|
+
false
|
771
|
+
end
|
772
|
+
end
|
773
|
+
if index
|
774
|
+
first_token = nil
|
775
|
+
last_line_tokens = tokens[(index + 1)..(tokens.size - 1)]
|
776
|
+
last_line_tokens.each do |t|
|
777
|
+
unless [:on_sp, :on_ignored_sp, :on_comment].include?(t.event)
|
778
|
+
first_token = t
|
779
|
+
break
|
780
|
+
end
|
781
|
+
end
|
782
|
+
if first_token.nil?
|
783
|
+
return false
|
784
|
+
elsif first_token && first_token.state == Ripper::EXPR_DOT
|
785
|
+
return false
|
786
|
+
else
|
787
|
+
tokens_without_last_line = tokens[0..index]
|
788
|
+
ltype = process_literal_type(tokens_without_last_line)
|
789
|
+
indent = process_nesting_level(tokens_without_last_line)
|
790
|
+
continue = process_continue(tokens_without_last_line)
|
791
|
+
code_block_open = check_code_block(tokens_without_last_line.map(&:tok).join(''), tokens_without_last_line)
|
792
|
+
if ltype or indent > 0 or continue or code_block_open
|
793
|
+
return false
|
794
|
+
else
|
795
|
+
return last_line_tokens.map(&:tok).join('')
|
796
|
+
end
|
797
|
+
end
|
798
|
+
end
|
799
|
+
false
|
800
|
+
end
|
741
801
|
end
|
742
802
|
# :startdoc:
|
data/lib/irb/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: irb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keiju ISHITSUKA
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-02
|
11
|
+
date: 2021-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: reline
|
@@ -77,10 +77,13 @@ files:
|
|
77
77
|
- lib/irb/cmd/help.rb
|
78
78
|
- lib/irb/cmd/info.rb
|
79
79
|
- lib/irb/cmd/load.rb
|
80
|
+
- lib/irb/cmd/ls.rb
|
80
81
|
- lib/irb/cmd/measure.rb
|
81
82
|
- lib/irb/cmd/nop.rb
|
82
83
|
- lib/irb/cmd/pushws.rb
|
84
|
+
- lib/irb/cmd/show_source.rb
|
83
85
|
- lib/irb/cmd/subirb.rb
|
86
|
+
- lib/irb/cmd/whereami.rb
|
84
87
|
- lib/irb/color.rb
|
85
88
|
- lib/irb/color_printer.rb
|
86
89
|
- lib/irb/completion.rb
|
@@ -137,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
140
|
- !ruby/object:Gem::Version
|
138
141
|
version: '0'
|
139
142
|
requirements: []
|
140
|
-
rubygems_version: 3.
|
143
|
+
rubygems_version: 3.1.4
|
141
144
|
signing_key:
|
142
145
|
specification_version: 4
|
143
146
|
summary: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).
|