irb 1.3.4 → 1.3.5
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/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).
|