irb 1.2.3 → 1.2.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -5
- data/irb.gemspec +2 -2
- data/lib/irb.rb +65 -16
- data/lib/irb/cmd/fork.rb +1 -3
- data/lib/irb/cmd/pushws.rb +0 -1
- data/lib/irb/color.rb +23 -21
- data/lib/irb/completion.rb +8 -9
- data/lib/irb/context.rb +16 -5
- data/lib/irb/easter-egg.rb +2 -1
- data/lib/irb/ext/change-ws.rb +0 -1
- data/lib/irb/ext/history.rb +0 -2
- data/lib/irb/ext/loader.rb +0 -1
- data/lib/irb/ext/save-history.rb +8 -5
- data/lib/irb/ext/tracer.rb +0 -1
- data/lib/irb/ext/use-loader.rb +1 -3
- data/lib/irb/ext/workspaces.rb +0 -1
- data/lib/irb/extend-command.rb +19 -8
- data/lib/irb/help.rb +0 -1
- data/lib/irb/init.rb +69 -3
- data/lib/irb/input-method.rb +53 -8
- data/lib/irb/inspector.rb +1 -5
- data/lib/irb/ruby-lex.rb +161 -46
- data/lib/irb/ruby_logo.aa +0 -1
- data/lib/irb/version.rb +2 -2
- data/lib/irb/workspace.rb +4 -2
- data/lib/irb/xmp.rb +1 -1
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ffc4aa655192040fa6afa339ebd3a440a0edab364b8adb43879b46b4437bb7d
|
4
|
+
data.tar.gz: b8abfe5e41f5685a487458d6c8dde123151b4e49814850d39bb54ac159614850
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb7613e840270144cf31aeeffa2ae70367492c79a47dcae24da0ff90c69ca8c089efb031f52972b50be02db816ad4e35a493b654f2a43e7639f1fdf9c55060e7
|
7
|
+
data.tar.gz: d587ad70d0d944a7c9f0ca58adff4adf0055d3d1f6aa3052f4d2783cf04f4184689d6e16dff173bddf1755543eedecd4308da6db113aca644502ce4aa46274d3
|
data/Gemfile
CHANGED
@@ -3,8 +3,3 @@ source "https://rubygems.org"
|
|
3
3
|
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
4
4
|
|
5
5
|
gemspec
|
6
|
-
|
7
|
-
# TODO: remove this when reline with `Reline::Unicode.escape_for_print` is released.
|
8
|
-
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0')
|
9
|
-
gem "reline", github: "ruby/reline"
|
10
|
-
end
|
data/irb.gemspec
CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.summary = %q{Interactive Ruby command-line tool for REPL (Read Eval Print Loop).}
|
15
15
|
spec.description = %q{Interactive Ruby command-line tool for REPL (Read Eval Print Loop).}
|
16
16
|
spec.homepage = "https://github.com/ruby/irb"
|
17
|
-
spec.
|
17
|
+
spec.licenses = ["Ruby", "BSD-2-Clause"]
|
18
18
|
|
19
19
|
spec.files = [
|
20
20
|
".document",
|
@@ -78,7 +78,7 @@ Gem::Specification.new do |spec|
|
|
78
78
|
|
79
79
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.5")
|
80
80
|
|
81
|
-
spec.add_dependency "reline", ">= 0.
|
81
|
+
spec.add_dependency "reline", ">= 0.1.5"
|
82
82
|
spec.add_development_dependency "bundler"
|
83
83
|
spec.add_development_dependency "rake"
|
84
84
|
end
|
data/lib/irb.rb
CHANGED
@@ -10,18 +10,19 @@
|
|
10
10
|
#
|
11
11
|
#
|
12
12
|
require "ripper"
|
13
|
+
require "reline"
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
require_relative "irb/init"
|
16
|
+
require_relative "irb/context"
|
17
|
+
require_relative "irb/extend-command"
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
require_relative "irb/ruby-lex"
|
20
|
+
require_relative "irb/input-method"
|
21
|
+
require_relative "irb/locale"
|
22
|
+
require_relative "irb/color"
|
22
23
|
|
23
|
-
|
24
|
-
|
24
|
+
require_relative "irb/version"
|
25
|
+
require_relative "irb/easter-egg"
|
25
26
|
|
26
27
|
# IRB stands for "interactive Ruby" and is a tool to interactively execute Ruby
|
27
28
|
# expressions read from the standard input.
|
@@ -271,7 +272,7 @@ require "irb/easter-egg"
|
|
271
272
|
# On the other hand, each conf in IRB@Command+line+options is used to
|
272
273
|
# individually configure IRB.irb.
|
273
274
|
#
|
274
|
-
# If a proc is set for IRB.conf[:IRB_RC]
|
275
|
+
# If a proc is set for <code>IRB.conf[:IRB_RC]</code>, its will be invoked after execution
|
275
276
|
# of that proc with the context of the current session as its argument. Each
|
276
277
|
# session can be configured using this mechanism.
|
277
278
|
#
|
@@ -399,7 +400,7 @@ module IRB
|
|
399
400
|
irb.run(@CONF)
|
400
401
|
end
|
401
402
|
|
402
|
-
# Calls each event hook of IRB.conf[:AT_EXIT] when the current session quits.
|
403
|
+
# Calls each event hook of <code>IRB.conf[:AT_EXIT]</code> when the current session quits.
|
403
404
|
def IRB.irb_at_exit
|
404
405
|
@CONF[:AT_EXIT].each{|hook| hook.call}
|
405
406
|
end
|
@@ -537,8 +538,32 @@ module IRB
|
|
537
538
|
signal_status(:IN_EVAL) do
|
538
539
|
begin
|
539
540
|
line.untaint if RUBY_VERSION < '2.7'
|
540
|
-
|
541
|
-
|
541
|
+
if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty?
|
542
|
+
IRB.set_measure_callback
|
543
|
+
end
|
544
|
+
if IRB.conf[:MEASURE] && !IRB.conf[:MEASURE_CALLBACKS].empty?
|
545
|
+
result = nil
|
546
|
+
last_proc = proc{ result = @context.evaluate(line, line_no, exception: exc) }
|
547
|
+
IRB.conf[:MEASURE_CALLBACKS].map{ |s| s.last }.inject(last_proc) { |chain, item|
|
548
|
+
proc {
|
549
|
+
item.(@context, line, line_no, exception: exc) do
|
550
|
+
chain.call
|
551
|
+
end
|
552
|
+
}
|
553
|
+
}.call
|
554
|
+
@context.set_last_value(result)
|
555
|
+
else
|
556
|
+
@context.evaluate(line, line_no, exception: exc)
|
557
|
+
end
|
558
|
+
if @context.echo?
|
559
|
+
if assignment_expression?(line)
|
560
|
+
if @context.echo_on_assignment?
|
561
|
+
output_value(@context.echo_on_assignment? == :truncate)
|
562
|
+
end
|
563
|
+
else
|
564
|
+
output_value
|
565
|
+
end
|
566
|
+
end
|
542
567
|
rescue Interrupt => exc
|
543
568
|
rescue SystemExit, SignalException
|
544
569
|
raise
|
@@ -554,7 +579,8 @@ module IRB
|
|
554
579
|
|
555
580
|
def handle_exception(exc)
|
556
581
|
if exc.backtrace && exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
|
557
|
-
!(SyntaxError === exc)
|
582
|
+
!(SyntaxError === exc) && !(EncodingError === exc)
|
583
|
+
# The backtrace of invalid encoding hash (ex. {"\xAE": 1}) raises EncodingError without lineno.
|
558
584
|
irb_bug = true
|
559
585
|
else
|
560
586
|
irb_bug = false
|
@@ -736,9 +762,32 @@ module IRB
|
|
736
762
|
p
|
737
763
|
end
|
738
764
|
|
739
|
-
def output_value # :nodoc:
|
765
|
+
def output_value(omit = false) # :nodoc:
|
740
766
|
str = @context.inspect_last_value
|
741
|
-
multiline_p =
|
767
|
+
multiline_p = str.include?("\n")
|
768
|
+
if omit
|
769
|
+
winwidth = @context.io.winsize.last
|
770
|
+
if multiline_p
|
771
|
+
first_line = str.split("\n").first
|
772
|
+
result = @context.newline_before_multiline_output? ? (@context.return_format % first_line) : first_line
|
773
|
+
output_width = Reline::Unicode.calculate_width(result, true)
|
774
|
+
diff_size = output_width - Reline::Unicode.calculate_width(first_line, true)
|
775
|
+
if diff_size.positive? and output_width > winwidth
|
776
|
+
lines, _ = Reline::Unicode.split_by_width(first_line, winwidth - diff_size - 3)
|
777
|
+
str = "%s...\e[0m" % lines.first
|
778
|
+
multiline_p = false
|
779
|
+
else
|
780
|
+
str = str.gsub(/(\A.*?\n).*/m, "\\1...")
|
781
|
+
end
|
782
|
+
else
|
783
|
+
output_width = Reline::Unicode.calculate_width(@context.return_format % str, true)
|
784
|
+
diff_size = output_width - Reline::Unicode.calculate_width(str, true)
|
785
|
+
if diff_size.positive? and output_width > winwidth
|
786
|
+
lines, _ = Reline::Unicode.split_by_width(str, winwidth - diff_size - 3)
|
787
|
+
str = "%s...\e[0m" % lines.first
|
788
|
+
end
|
789
|
+
end
|
790
|
+
end
|
742
791
|
if multiline_p && @context.newline_before_multiline_output?
|
743
792
|
printf @context.return_format, "\n#{str}"
|
744
793
|
else
|
data/lib/irb/cmd/fork.rb
CHANGED
@@ -16,7 +16,7 @@ module IRB
|
|
16
16
|
module ExtendCommand
|
17
17
|
class Fork < Nop
|
18
18
|
def execute
|
19
|
-
pid =
|
19
|
+
pid = __send__ ExtendCommand.irb_original_method_name("fork")
|
20
20
|
unless pid
|
21
21
|
class << self
|
22
22
|
alias_method :exit, ExtendCommand.irb_original_method_name('exit')
|
@@ -35,5 +35,3 @@ module IRB
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
# :startdoc:
|
38
|
-
|
39
|
-
|
data/lib/irb/cmd/pushws.rb
CHANGED
data/lib/irb/color.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'reline'
|
3
3
|
require 'ripper'
|
4
|
+
require 'irb/ruby-lex'
|
4
5
|
|
5
6
|
module IRB # :nodoc:
|
6
7
|
module Color
|
@@ -145,37 +146,38 @@ module IRB # :nodoc:
|
|
145
146
|
seen.delete(obj)
|
146
147
|
end
|
147
148
|
|
148
|
-
# Ripper::Lexer::Elem#state is supported on Ruby 2.5+
|
149
149
|
def supported?
|
150
150
|
return @supported if defined?(@supported)
|
151
|
-
@supported =
|
151
|
+
@supported = Ripper::Lexer::Elem.method_defined?(:state)
|
152
152
|
end
|
153
153
|
|
154
154
|
def scan(code, allow_last_error:)
|
155
155
|
pos = [1, 0]
|
156
156
|
|
157
157
|
verbose, $VERBOSE = $VERBOSE, nil
|
158
|
-
|
159
|
-
|
160
|
-
lexer.scan
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
158
|
+
RubyLex.compile_with_errors_suppressed(code) do |inner_code, line_no|
|
159
|
+
lexer = Ripper::Lexer.new(inner_code, '(ripper)', line_no)
|
160
|
+
if lexer.respond_to?(:scan) # Ruby 2.7+
|
161
|
+
lexer.scan.each do |elem|
|
162
|
+
str = elem.tok
|
163
|
+
next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message
|
164
|
+
next if ([elem.pos[0], elem.pos[1] + str.bytesize] <=> pos) <= 0
|
165
|
+
|
166
|
+
str.each_line do |line|
|
167
|
+
if line.end_with?("\n")
|
168
|
+
pos[0] += 1
|
169
|
+
pos[1] = 0
|
170
|
+
else
|
171
|
+
pos[1] += line.bytesize
|
172
|
+
end
|
171
173
|
end
|
172
|
-
end
|
173
174
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
175
|
+
yield(elem.event, str, elem.state)
|
176
|
+
end
|
177
|
+
else
|
178
|
+
lexer.parse.each do |elem|
|
179
|
+
yield(elem.event, elem.tok, elem.state)
|
180
|
+
end
|
179
181
|
end
|
180
182
|
end
|
181
183
|
$VERBOSE = verbose
|
data/lib/irb/completion.rb
CHANGED
@@ -7,7 +7,6 @@
|
|
7
7
|
# From Original Idea of shugo@ruby-lang.org
|
8
8
|
#
|
9
9
|
|
10
|
-
require "readline"
|
11
10
|
autoload :RDoc, "rdoc"
|
12
11
|
|
13
12
|
module IRB
|
@@ -97,13 +96,13 @@ module IRB
|
|
97
96
|
when /^(:[^:.]*)$/
|
98
97
|
# Symbol
|
99
98
|
return nil if doc_namespace
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
[]
|
99
|
+
sym = $1
|
100
|
+
candidates = Symbol.all_symbols.collect do |s|
|
101
|
+
":" + s.id2name.encode(Encoding.default_external)
|
102
|
+
rescue Encoding::UndefinedConversionError
|
103
|
+
# ignore
|
106
104
|
end
|
105
|
+
candidates.grep(/^#{Regexp.quote(sym)}/)
|
107
106
|
|
108
107
|
when /^::([A-Z][^:\.\(]*)$/
|
109
108
|
# Absolute Constant or class methods
|
@@ -144,7 +143,7 @@ module IRB
|
|
144
143
|
select_message(receiver, message, candidates, sep)
|
145
144
|
end
|
146
145
|
|
147
|
-
when /^(?<num>-?(0[dbo])?[0-9_]+(
|
146
|
+
when /^(?<num>-?(?:0[dbo])?[0-9_]+(?:\.[0-9_]+)?(?:(?:[eE][+-]?[0-9]+)?i?|r)?)(?<sep>\.|::)(?<mes>[^.]*)$/
|
148
147
|
# Numeric
|
149
148
|
receiver = $~[:num]
|
150
149
|
sep = $~[:sep]
|
@@ -269,7 +268,7 @@ module IRB
|
|
269
268
|
PerfectMatchedProc = ->(matched, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding) {
|
270
269
|
RDocRIDriver ||= RDoc::RI::Driver.new
|
271
270
|
if matched =~ /\A(?:::)?RubyVM/ and not ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
|
272
|
-
IRB.
|
271
|
+
IRB.__send__(:easter_egg)
|
273
272
|
return
|
274
273
|
end
|
275
274
|
namespace = retrieve_completion_data(matched, bind: bind, doc_namespace: true)
|
data/lib/irb/context.rb
CHANGED
@@ -131,7 +131,7 @@ module IRB
|
|
131
131
|
|
132
132
|
@echo_on_assignment = IRB.conf[:ECHO_ON_ASSIGNMENT]
|
133
133
|
if @echo_on_assignment.nil?
|
134
|
-
@echo_on_assignment =
|
134
|
+
@echo_on_assignment = :truncate
|
135
135
|
end
|
136
136
|
|
137
137
|
@newline_before_multiline_output = IRB.conf[:NEWLINE_BEFORE_MULTILINE_OUTPUT]
|
@@ -240,7 +240,7 @@ module IRB
|
|
240
240
|
attr_accessor :ignore_eof
|
241
241
|
# Whether to echo the return value to output or not.
|
242
242
|
#
|
243
|
-
# Uses IRB.conf[:ECHO] if available, or defaults to +true+.
|
243
|
+
# Uses <code>IRB.conf[:ECHO]</code> if available, or defaults to +true+.
|
244
244
|
#
|
245
245
|
# puts "hello"
|
246
246
|
# # hello
|
@@ -251,16 +251,27 @@ module IRB
|
|
251
251
|
attr_accessor :echo
|
252
252
|
# Whether to echo for assignment expressions
|
253
253
|
#
|
254
|
-
#
|
254
|
+
# If set to +false+, the value of assignment will not be shown.
|
255
|
+
#
|
256
|
+
# If set to +true+, the value of assignment will be shown.
|
257
|
+
#
|
258
|
+
# If set to +:truncate+, the value of assignment will be shown and truncated.
|
259
|
+
#
|
260
|
+
# It defaults to +:truncate+.
|
255
261
|
#
|
256
262
|
# a = "omg"
|
263
|
+
# #=> omg
|
264
|
+
# a = "omg" * 10
|
265
|
+
# #=> omgomgomgomgomgomgomg...
|
266
|
+
# IRB.CurrentContext.echo_on_assignment = false
|
267
|
+
# a = "omg"
|
257
268
|
# IRB.CurrentContext.echo_on_assignment = true
|
258
269
|
# a = "omg"
|
259
|
-
# #=>
|
270
|
+
# #=> omgomgomgomgomgomgomgomgomgomg
|
260
271
|
attr_accessor :echo_on_assignment
|
261
272
|
# Whether a newline is put before multiline output.
|
262
273
|
#
|
263
|
-
# Uses IRB.conf[:NEWLINE_BEFORE_MULTILINE_OUTPUT] if available,
|
274
|
+
# Uses <code>IRB.conf[:NEWLINE_BEFORE_MULTILINE_OUTPUT]</code> if available,
|
264
275
|
# or defaults to +true+.
|
265
276
|
#
|
266
277
|
# "abc\ndef"
|
data/lib/irb/easter-egg.rb
CHANGED
@@ -126,6 +126,7 @@ module IRB
|
|
126
126
|
print "\e[H" + buff
|
127
127
|
sleep 0.05
|
128
128
|
end
|
129
|
+
rescue Interrupt
|
129
130
|
ensure
|
130
131
|
print "\e[0m\e[?1049l"
|
131
132
|
end
|
@@ -134,4 +135,4 @@ module IRB
|
|
134
135
|
end
|
135
136
|
end
|
136
137
|
|
137
|
-
IRB.
|
138
|
+
IRB.__send__(:easter_egg, ARGV[0]&.to_sym) if $0 == __FILE__
|
data/lib/irb/ext/change-ws.rb
CHANGED
data/lib/irb/ext/history.rb
CHANGED
data/lib/irb/ext/loader.rb
CHANGED
data/lib/irb/ext/save-history.rb
CHANGED
@@ -9,8 +9,6 @@
|
|
9
9
|
#
|
10
10
|
#
|
11
11
|
|
12
|
-
require "readline"
|
13
|
-
|
14
12
|
module IRB
|
15
13
|
module HistorySavingAbility # :nodoc:
|
16
14
|
end
|
@@ -27,7 +25,7 @@ module IRB
|
|
27
25
|
IRB.conf[:SAVE_HISTORY]
|
28
26
|
end
|
29
27
|
|
30
|
-
remove_method
|
28
|
+
remove_method(:save_history=) if method_defined?(:save_history=)
|
31
29
|
# Sets <code>IRB.conf[:SAVE_HISTORY]</code> to the given +val+ and calls
|
32
30
|
# #init_save_history with this context.
|
33
31
|
#
|
@@ -89,7 +87,7 @@ module IRB
|
|
89
87
|
def save_history
|
90
88
|
return unless self.class.const_defined?(:HISTORY)
|
91
89
|
history = self.class::HISTORY
|
92
|
-
if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i)
|
90
|
+
if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) != 0
|
93
91
|
if history_file = IRB.conf[:HISTORY_FILE]
|
94
92
|
history_file = File.expand_path(history_file)
|
95
93
|
end
|
@@ -109,7 +107,12 @@ module IRB
|
|
109
107
|
|
110
108
|
open(history_file, "w:#{IRB.conf[:LC_MESSAGES].encoding}", 0600) do |f|
|
111
109
|
hist = history.map{ |l| l.split("\n").join("\\\n") }
|
112
|
-
|
110
|
+
begin
|
111
|
+
hist = hist.last(num) if hist.size > num and num > 0
|
112
|
+
rescue RangeError # bignum too big to convert into `long'
|
113
|
+
# Do nothing because the bignum should be treated as inifinity
|
114
|
+
end
|
115
|
+
f.puts(hist)
|
113
116
|
end
|
114
117
|
end
|
115
118
|
end
|
data/lib/irb/ext/tracer.rb
CHANGED
data/lib/irb/ext/use-loader.rb
CHANGED
@@ -47,7 +47,7 @@ module IRB
|
|
47
47
|
alias use_loader? use_loader
|
48
48
|
|
49
49
|
remove_method :use_loader= if method_defined?(:use_loader=)
|
50
|
-
# Sets IRB.conf[:USE_LOADER]
|
50
|
+
# Sets <code>IRB.conf[:USE_LOADER]</code>
|
51
51
|
#
|
52
52
|
# See #use_loader for more information.
|
53
53
|
def use_loader=(opt)
|
@@ -73,5 +73,3 @@ module IRB
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
76
|
-
|
77
|
-
|
data/lib/irb/ext/workspaces.rb
CHANGED
data/lib/irb/extend-command.rb
CHANGED
@@ -121,6 +121,14 @@ module IRB # :nodoc:
|
|
121
121
|
[:help, NO_OVERRIDE],
|
122
122
|
],
|
123
123
|
|
124
|
+
[
|
125
|
+
:irb_info, :Info, "irb/cmd/info"
|
126
|
+
],
|
127
|
+
|
128
|
+
[
|
129
|
+
:measure, :Measure, "irb/cmd/measure"
|
130
|
+
],
|
131
|
+
|
124
132
|
]
|
125
133
|
|
126
134
|
# Installs the default irb commands:
|
@@ -169,11 +177,14 @@ module IRB # :nodoc:
|
|
169
177
|
args << "&block"
|
170
178
|
args = args.join(", ")
|
171
179
|
line = __LINE__; eval %[
|
172
|
-
|
173
|
-
|
180
|
+
unless self.class.class_variable_defined?(:@@#{cmd_name}_)
|
181
|
+
self.class.class_variable_set(:@@#{cmd_name}_, true)
|
182
|
+
def #{cmd_name}_(\#{args})
|
183
|
+
ExtendCommand::#{cmd_class}.execute(irb_context, \#{args})
|
184
|
+
end
|
174
185
|
end
|
175
186
|
], nil, __FILE__, line
|
176
|
-
|
187
|
+
__send__ :#{cmd_name}_, *opts, &b
|
177
188
|
end
|
178
189
|
], nil, __FILE__, line
|
179
190
|
else
|
@@ -261,7 +272,7 @@ module IRB # :nodoc:
|
|
261
272
|
def #{cmd_name}(*opts, &b)
|
262
273
|
Context.module_eval {remove_method(:#{cmd_name})}
|
263
274
|
require "#{load_file}"
|
264
|
-
|
275
|
+
__send__ :#{cmd_name}, *opts, &b
|
265
276
|
end
|
266
277
|
for ali in aliases
|
267
278
|
alias_method ali, cmd_name
|
@@ -284,8 +295,8 @@ module IRB # :nodoc:
|
|
284
295
|
module_eval %[
|
285
296
|
alias_method alias_name, base_method
|
286
297
|
def #{base_method}(*opts)
|
287
|
-
|
288
|
-
|
298
|
+
__send__ :#{extend_method}, *opts
|
299
|
+
__send__ :#{alias_name}, *opts
|
289
300
|
end
|
290
301
|
]
|
291
302
|
end
|
@@ -300,8 +311,8 @@ module IRB # :nodoc:
|
|
300
311
|
module_eval %[
|
301
312
|
alias_method alias_name, base_method
|
302
313
|
def #{base_method}(*opts)
|
303
|
-
|
304
|
-
|
314
|
+
__send__ :#{alias_name}, *opts
|
315
|
+
__send__ :#{extend_method}, *opts
|
305
316
|
end
|
306
317
|
]
|
307
318
|
end
|
data/lib/irb/help.rb
CHANGED
data/lib/irb/init.rb
CHANGED
@@ -108,14 +108,69 @@ module IRB # :nodoc:
|
|
108
108
|
@CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL)
|
109
109
|
@CONF[:AUTO_INDENT] = true
|
110
110
|
|
111
|
-
@CONF[:CONTEXT_MODE] =
|
111
|
+
@CONF[:CONTEXT_MODE] = 4 # use a copy of TOPLEVEL_BINDING
|
112
112
|
@CONF[:SINGLE_IRB] = false
|
113
113
|
|
114
|
+
@CONF[:MEASURE] = false
|
115
|
+
@CONF[:MEASURE_PROC] = {}
|
116
|
+
@CONF[:MEASURE_PROC][:TIME] = proc { |context, code, line_no, &block|
|
117
|
+
time = Time.now
|
118
|
+
result = block.()
|
119
|
+
now = Time.now
|
120
|
+
puts 'processing time: %fs' % (now - time) if IRB.conf[:MEASURE]
|
121
|
+
result
|
122
|
+
}
|
123
|
+
@CONF[:MEASURE_PROC][:STACKPROF] = proc { |context, code, line_no, &block|
|
124
|
+
success = false
|
125
|
+
begin
|
126
|
+
require 'stackprof'
|
127
|
+
success = true
|
128
|
+
rescue LoadError
|
129
|
+
puts 'Please run "gem install stackprof" before measuring by StackProf.'
|
130
|
+
end
|
131
|
+
if success
|
132
|
+
result = nil
|
133
|
+
stackprof_result = StackProf.run(mode: :cpu) do
|
134
|
+
result = block.()
|
135
|
+
end
|
136
|
+
StackProf::Report.new(stackprof_result).print_text if IRB.conf[:MEASURE]
|
137
|
+
result
|
138
|
+
else
|
139
|
+
block.()
|
140
|
+
end
|
141
|
+
}
|
142
|
+
@CONF[:MEASURE_CALLBACKS] = []
|
143
|
+
|
114
144
|
@CONF[:LC_MESSAGES] = Locale.new
|
115
145
|
|
116
146
|
@CONF[:AT_EXIT] = []
|
117
147
|
end
|
118
148
|
|
149
|
+
def IRB.set_measure_callback(type = nil)
|
150
|
+
added = nil
|
151
|
+
if type
|
152
|
+
type_sym = type.upcase.to_sym
|
153
|
+
if IRB.conf[:MEASURE_PROC][type_sym]
|
154
|
+
added = [type_sym, IRB.conf[:MEASURE_PROC][type_sym]]
|
155
|
+
end
|
156
|
+
elsif IRB.conf[:MEASURE_PROC][:CUSTOM]
|
157
|
+
added = [:CUSTOM, IRB.conf[:MEASURE_PROC][:CUSTOM]]
|
158
|
+
else
|
159
|
+
added = [:TIME, IRB.conf[:MEASURE_PROC][:TIME]]
|
160
|
+
end
|
161
|
+
IRB.conf[:MEASURE_CALLBACKS] << added if added
|
162
|
+
added
|
163
|
+
end
|
164
|
+
|
165
|
+
def IRB.unset_measure_callback(type = nil)
|
166
|
+
if type.nil?
|
167
|
+
IRB.conf[:MEASURE_CALLBACKS].clear
|
168
|
+
else
|
169
|
+
type_sym = type.upcase.to_sym
|
170
|
+
IRB.conf[:MEASURE_CALLBACKS].reject!{ |t, c| t == type_sym }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
119
174
|
def IRB.init_error
|
120
175
|
@CONF[:LC_MESSAGES].load("irb/error.rb")
|
121
176
|
end
|
@@ -131,7 +186,7 @@ module IRB # :nodoc:
|
|
131
186
|
$DEBUG = true
|
132
187
|
$VERBOSE = true
|
133
188
|
when "-w"
|
134
|
-
$VERBOSE = true
|
189
|
+
Warning[:deprecated] = $VERBOSE = true
|
135
190
|
when /^-W(.+)?/
|
136
191
|
opt = $1 || argv.shift
|
137
192
|
case opt
|
@@ -140,7 +195,7 @@ module IRB # :nodoc:
|
|
140
195
|
when "1"
|
141
196
|
$VERBOSE = false
|
142
197
|
else
|
143
|
-
$VERBOSE = true
|
198
|
+
Warning[:deprecated] = $VERBOSE = true
|
144
199
|
end
|
145
200
|
when /^-r(.+)?/
|
146
201
|
opt = $1 || argv.shift
|
@@ -177,6 +232,8 @@ module IRB # :nodoc:
|
|
177
232
|
@CONF[:ECHO_ON_ASSIGNMENT] = true
|
178
233
|
when "--noecho-on-assignment"
|
179
234
|
@CONF[:ECHO_ON_ASSIGNMENT] = false
|
235
|
+
when "--truncate-echo-on-assignment"
|
236
|
+
@CONF[:ECHO_ON_ASSIGNMENT] = :truncate
|
180
237
|
when "--verbose"
|
181
238
|
@CONF[:VERBOSE] = true
|
182
239
|
when "--noverbose"
|
@@ -271,10 +328,19 @@ module IRB # :nodoc:
|
|
271
328
|
if irbrc = ENV["IRBRC"]
|
272
329
|
yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc}
|
273
330
|
end
|
331
|
+
if xdg_config_home = ENV["XDG_CONFIG_HOME"]
|
332
|
+
irb_home = File.join(xdg_config_home, "irb")
|
333
|
+
unless File.exist? irb_home
|
334
|
+
require 'fileutils'
|
335
|
+
FileUtils.mkdir_p irb_home
|
336
|
+
end
|
337
|
+
yield proc{|rc| irb_home + "/irb#{rc}"}
|
338
|
+
end
|
274
339
|
if home = ENV["HOME"]
|
275
340
|
yield proc{|rc| home+"/.irb#{rc}"}
|
276
341
|
end
|
277
342
|
current_dir = Dir.pwd
|
343
|
+
yield proc{|rc| current_dir+"/.config/irb/irb#{rc}"}
|
278
344
|
yield proc{|rc| current_dir+"/.irb#{rc}"}
|
279
345
|
yield proc{|rc| current_dir+"/irb#{rc.sub(/\A_?/, '.')}"}
|
280
346
|
yield proc{|rc| current_dir+"/_irb#{rc}"}
|
data/lib/irb/input-method.rb
CHANGED
@@ -12,6 +12,7 @@
|
|
12
12
|
require_relative 'src_encoding'
|
13
13
|
require_relative 'magic-file'
|
14
14
|
require_relative 'completion'
|
15
|
+
require 'io/console'
|
15
16
|
require 'reline'
|
16
17
|
|
17
18
|
module IRB
|
@@ -36,6 +37,14 @@ module IRB
|
|
36
37
|
end
|
37
38
|
public :gets
|
38
39
|
|
40
|
+
def winsize
|
41
|
+
if instance_variable_defined?(:@stdout)
|
42
|
+
@stdout.winsize
|
43
|
+
else
|
44
|
+
[24, 80]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
39
48
|
# Whether this input method is still readable when there is no more data to
|
40
49
|
# read.
|
41
50
|
#
|
@@ -43,6 +52,11 @@ module IRB
|
|
43
52
|
def readable_after_eof?
|
44
53
|
false
|
45
54
|
end
|
55
|
+
|
56
|
+
# For debug message
|
57
|
+
def inspect
|
58
|
+
'Abstract InputMethod'
|
59
|
+
end
|
46
60
|
end
|
47
61
|
|
48
62
|
class StdioInputMethod < InputMethod
|
@@ -93,6 +107,11 @@ module IRB
|
|
93
107
|
def encoding
|
94
108
|
@stdin.external_encoding
|
95
109
|
end
|
110
|
+
|
111
|
+
# For debug message
|
112
|
+
def inspect
|
113
|
+
'StdioInputMethod'
|
114
|
+
end
|
96
115
|
end
|
97
116
|
|
98
117
|
# Use a File for IO with irb, see InputMethod
|
@@ -125,14 +144,25 @@ module IRB
|
|
125
144
|
def encoding
|
126
145
|
@io.external_encoding
|
127
146
|
end
|
147
|
+
|
148
|
+
# For debug message
|
149
|
+
def inspect
|
150
|
+
'FileInputMethod'
|
151
|
+
end
|
128
152
|
end
|
129
153
|
|
130
154
|
begin
|
131
|
-
require "readline"
|
132
155
|
class ReadlineInputMethod < InputMethod
|
133
|
-
|
156
|
+
def self.initialize_readline
|
157
|
+
require "readline"
|
158
|
+
rescue LoadError
|
159
|
+
else
|
160
|
+
include ::Readline
|
161
|
+
end
|
162
|
+
|
134
163
|
# Creates a new input method object using Readline
|
135
164
|
def initialize
|
165
|
+
self.class.initialize_readline
|
136
166
|
if Readline.respond_to?(:encoding_system_needs)
|
137
167
|
IRB.__send__(:set_encoding, Readline.encoding_system_needs.name, override: false)
|
138
168
|
end
|
@@ -197,13 +227,15 @@ module IRB
|
|
197
227
|
@stdin.external_encoding
|
198
228
|
end
|
199
229
|
|
200
|
-
|
201
|
-
|
230
|
+
# For debug message
|
231
|
+
def inspect
|
232
|
+
readline_impl = (defined?(Reline) && Readline == Reline) ? 'Reline' : 'ext/readline'
|
233
|
+
str = "ReadlineInputMethod with #{readline_impl} #{Readline::VERSION}"
|
234
|
+
inputrc_path = File.expand_path(ENV['INPUTRC'] || '~/.inputrc')
|
235
|
+
str += " and #{inputrc_path}" if File.exist?(inputrc_path)
|
236
|
+
str
|
202
237
|
end
|
203
|
-
Readline.completion_append_character = nil
|
204
|
-
Readline.completion_proc = IRB::InputCompletor::CompletionProc
|
205
238
|
end
|
206
|
-
rescue LoadError
|
207
239
|
end
|
208
240
|
|
209
241
|
class ReidlineInputMethod < InputMethod
|
@@ -227,7 +259,7 @@ module IRB
|
|
227
259
|
Reline.completion_proc = IRB::InputCompletor::CompletionProc
|
228
260
|
Reline.output_modifier_proc =
|
229
261
|
if IRB.conf[:USE_COLORIZE]
|
230
|
-
proc do |output, complete
|
262
|
+
proc do |output, complete: |
|
231
263
|
next unless IRB::Color.colorable?
|
232
264
|
IRB::Color.colorize_code(output, complete: complete)
|
233
265
|
end
|
@@ -297,5 +329,18 @@ module IRB
|
|
297
329
|
def encoding
|
298
330
|
@stdin.external_encoding
|
299
331
|
end
|
332
|
+
|
333
|
+
# For debug message
|
334
|
+
def inspect
|
335
|
+
config = Reline::Config.new
|
336
|
+
str = "ReidlineInputMethod with Reline #{Reline::VERSION}"
|
337
|
+
if config.respond_to?(:inputrc_path)
|
338
|
+
inputrc_path = File.expand_path(config.inputrc_path)
|
339
|
+
else
|
340
|
+
inputrc_path = File.expand_path(ENV['INPUTRC'] || '~/.inputrc')
|
341
|
+
end
|
342
|
+
str += " and #{inputrc_path}" if File.exist?(inputrc_path)
|
343
|
+
str
|
344
|
+
end
|
300
345
|
end
|
301
346
|
end
|
data/lib/irb/inspector.rb
CHANGED
@@ -113,6 +113,7 @@ module IRB # :nodoc:
|
|
113
113
|
result
|
114
114
|
rescue NoMethodError
|
115
115
|
puts "(Object doesn't support #inspect)"
|
116
|
+
''
|
116
117
|
end
|
117
118
|
}
|
118
119
|
Inspector.def_inspector([:pp, :pretty_inspect], proc{require "pp"}){|v|
|
@@ -135,8 +136,3 @@ module IRB # :nodoc:
|
|
135
136
|
Marshal.dump(v)
|
136
137
|
}
|
137
138
|
end
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
data/lib/irb/ruby-lex.rb
CHANGED
@@ -11,6 +11,7 @@
|
|
11
11
|
#
|
12
12
|
|
13
13
|
require "ripper"
|
14
|
+
require "jruby" if RUBY_ENGINE == "jruby"
|
14
15
|
|
15
16
|
# :stopdoc:
|
16
17
|
class RubyLex
|
@@ -29,6 +30,18 @@ class RubyLex
|
|
29
30
|
@prompt = nil
|
30
31
|
end
|
31
32
|
|
33
|
+
def self.compile_with_errors_suppressed(code)
|
34
|
+
line_no = 1
|
35
|
+
begin
|
36
|
+
result = yield code, line_no
|
37
|
+
rescue ArgumentError
|
38
|
+
code = ";\n#{code}"
|
39
|
+
line_no = 0
|
40
|
+
result = yield code, line_no
|
41
|
+
end
|
42
|
+
result
|
43
|
+
end
|
44
|
+
|
32
45
|
# io functions
|
33
46
|
def set_input(io, p = nil, &block)
|
34
47
|
@io = io
|
@@ -47,11 +60,26 @@ class RubyLex
|
|
47
60
|
@io.dynamic_prompt do |lines|
|
48
61
|
lines << '' if lines.empty?
|
49
62
|
result = []
|
50
|
-
lines.
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
63
|
+
tokens = ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join)
|
64
|
+
code = String.new
|
65
|
+
partial_tokens = []
|
66
|
+
unprocessed_tokens = []
|
67
|
+
line_num_offset = 0
|
68
|
+
tokens.each do |t|
|
69
|
+
code << t[2]
|
70
|
+
partial_tokens << t
|
71
|
+
unprocessed_tokens << t
|
72
|
+
if t[2].include?("\n")
|
73
|
+
ltype, indent, continue, code_block_open = check_state(code, partial_tokens)
|
74
|
+
result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
|
75
|
+
line_num_offset += 1
|
76
|
+
unprocessed_tokens = []
|
77
|
+
end
|
78
|
+
end
|
79
|
+
unless unprocessed_tokens.empty?
|
80
|
+
ltype, indent, continue, code_block_open = check_state(code, unprocessed_tokens)
|
81
|
+
result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
|
82
|
+
end
|
55
83
|
result
|
56
84
|
end
|
57
85
|
end
|
@@ -75,7 +103,10 @@ class RubyLex
|
|
75
103
|
|
76
104
|
def ripper_lex_without_warning(code)
|
77
105
|
verbose, $VERBOSE = $VERBOSE, nil
|
78
|
-
tokens =
|
106
|
+
tokens = nil
|
107
|
+
self.class.compile_with_errors_suppressed(code) do |inner_code, line_no|
|
108
|
+
tokens = Ripper.lex(inner_code, '-', line_no)
|
109
|
+
end
|
79
110
|
$VERBOSE = verbose
|
80
111
|
tokens
|
81
112
|
end
|
@@ -105,12 +136,12 @@ class RubyLex
|
|
105
136
|
end
|
106
137
|
end
|
107
138
|
|
108
|
-
def check_state(code)
|
109
|
-
|
110
|
-
ltype = process_literal_type
|
111
|
-
indent = process_nesting_level
|
112
|
-
continue = process_continue
|
113
|
-
code_block_open = check_code_block(code)
|
139
|
+
def check_state(code, tokens = nil)
|
140
|
+
tokens = ripper_lex_without_warning(code) unless tokens
|
141
|
+
ltype = process_literal_type(tokens)
|
142
|
+
indent = process_nesting_level(tokens)
|
143
|
+
continue = process_continue(tokens)
|
144
|
+
code_block_open = check_code_block(code, tokens)
|
114
145
|
[ltype, indent, continue, code_block_open]
|
115
146
|
end
|
116
147
|
|
@@ -170,47 +201,56 @@ class RubyLex
|
|
170
201
|
code = @line + (line.nil? ? '' : line)
|
171
202
|
code.gsub!(/\s*\z/, '').concat("\n")
|
172
203
|
@tokens = ripper_lex_without_warning(code)
|
173
|
-
@continue = process_continue
|
174
|
-
@code_block_open = check_code_block(code)
|
175
|
-
@indent = process_nesting_level
|
176
|
-
@ltype = process_literal_type
|
204
|
+
@continue = process_continue(@tokens)
|
205
|
+
@code_block_open = check_code_block(code, @tokens)
|
206
|
+
@indent = process_nesting_level(@tokens)
|
207
|
+
@ltype = process_literal_type(@tokens)
|
177
208
|
line
|
178
209
|
end
|
179
210
|
|
180
|
-
def process_continue
|
211
|
+
def process_continue(tokens)
|
181
212
|
# last token is always newline
|
182
|
-
if
|
213
|
+
if tokens.size >= 2 and tokens[-2][1] == :on_regexp_end
|
183
214
|
# end of regexp literal
|
184
215
|
return false
|
185
|
-
elsif
|
216
|
+
elsif tokens.size >= 2 and tokens[-2][1] == :on_semicolon
|
186
217
|
return false
|
187
|
-
elsif
|
218
|
+
elsif tokens.size >= 2 and tokens[-2][1] == :on_kw and ['begin', 'else', 'ensure'].include?(tokens[-2][2])
|
188
219
|
return false
|
189
|
-
elsif
|
220
|
+
elsif !tokens.empty? and tokens.last[2] == "\\\n"
|
190
221
|
return true
|
191
|
-
elsif
|
222
|
+
elsif tokens.size >= 1 and tokens[-1][1] == :on_heredoc_end # "EOH\n"
|
192
223
|
return false
|
193
|
-
elsif
|
224
|
+
elsif tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and tokens[-2][3].anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME)
|
194
225
|
# end of literal except for regexp
|
195
226
|
return true
|
196
227
|
end
|
197
228
|
false
|
198
229
|
end
|
199
230
|
|
200
|
-
def check_code_block(code)
|
201
|
-
return true if
|
202
|
-
if
|
231
|
+
def check_code_block(code, tokens)
|
232
|
+
return true if tokens.empty?
|
233
|
+
if tokens.last[1] == :on_heredoc_beg
|
203
234
|
return true
|
204
235
|
end
|
205
236
|
|
206
237
|
begin # check if parser error are available
|
207
238
|
verbose, $VERBOSE = $VERBOSE, nil
|
208
239
|
case RUBY_ENGINE
|
240
|
+
when 'ruby'
|
241
|
+
self.class.compile_with_errors_suppressed(code) do |inner_code, line_no|
|
242
|
+
RubyVM::InstructionSequence.compile(inner_code, nil, nil, line_no)
|
243
|
+
end
|
209
244
|
when 'jruby'
|
210
245
|
JRuby.compile_ir(code)
|
211
246
|
else
|
212
|
-
|
247
|
+
catch(:valid) do
|
248
|
+
eval("BEGIN { throw :valid, true }\n#{code}")
|
249
|
+
false
|
250
|
+
end
|
213
251
|
end
|
252
|
+
rescue EncodingError
|
253
|
+
# This is for a hash with invalid encoding symbol, {"\xAE": 1}
|
214
254
|
rescue SyntaxError => e
|
215
255
|
case e.message
|
216
256
|
when /unterminated (?:string|regexp) meets end of file/
|
@@ -262,7 +302,7 @@ class RubyLex
|
|
262
302
|
end
|
263
303
|
|
264
304
|
if defined?(Ripper::EXPR_BEG)
|
265
|
-
last_lex_state =
|
305
|
+
last_lex_state = tokens.last[3]
|
266
306
|
if last_lex_state.allbits?(Ripper::EXPR_BEG)
|
267
307
|
return false
|
268
308
|
elsif last_lex_state.allbits?(Ripper::EXPR_DOT)
|
@@ -281,19 +321,41 @@ class RubyLex
|
|
281
321
|
false
|
282
322
|
end
|
283
323
|
|
284
|
-
def process_nesting_level
|
324
|
+
def process_nesting_level(tokens)
|
285
325
|
indent = 0
|
286
|
-
|
326
|
+
in_oneliner_def = nil
|
327
|
+
tokens.each_with_index { |t, index|
|
328
|
+
# detecting one-liner method definition
|
329
|
+
if in_oneliner_def.nil?
|
330
|
+
if t[3].allbits?(Ripper::EXPR_ENDFN)
|
331
|
+
in_oneliner_def = :ENDFN
|
332
|
+
end
|
333
|
+
else
|
334
|
+
if t[3].allbits?(Ripper::EXPR_ENDFN)
|
335
|
+
# continuing
|
336
|
+
elsif t[3].allbits?(Ripper::EXPR_BEG)
|
337
|
+
if t[2] == '='
|
338
|
+
in_oneliner_def = :BODY
|
339
|
+
end
|
340
|
+
else
|
341
|
+
if in_oneliner_def == :BODY
|
342
|
+
# one-liner method definition
|
343
|
+
indent -= 1
|
344
|
+
end
|
345
|
+
in_oneliner_def = nil
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
287
349
|
case t[1]
|
288
|
-
when :on_lbracket, :on_lbrace, :on_lparen
|
350
|
+
when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
|
289
351
|
indent += 1
|
290
352
|
when :on_rbracket, :on_rbrace, :on_rparen
|
291
353
|
indent -= 1
|
292
354
|
when :on_kw
|
293
|
-
next if index > 0 and
|
355
|
+
next if index > 0 and tokens[index - 1][3].allbits?(Ripper::EXPR_FNAME)
|
294
356
|
case t[2]
|
295
357
|
when 'do'
|
296
|
-
if index > 0 and
|
358
|
+
if index > 0 and tokens[index - 1][3].anybits?(Ripper::EXPR_CMDARG | Ripper::EXPR_ENDFN | Ripper::EXPR_ARG)
|
297
359
|
# method_with_block do; end
|
298
360
|
indent += 1
|
299
361
|
else
|
@@ -304,7 +366,7 @@ class RubyLex
|
|
304
366
|
when 'def', 'case', 'for', 'begin', 'class', 'module'
|
305
367
|
indent += 1
|
306
368
|
when 'if', 'unless', 'while', 'until'
|
307
|
-
# postfix if/unless/while/until
|
369
|
+
# postfix if/unless/while/until must be Ripper::EXPR_LABEL
|
308
370
|
indent += 1 unless t[3].allbits?(Ripper::EXPR_LABEL)
|
309
371
|
when 'end'
|
310
372
|
indent -= 1
|
@@ -318,7 +380,29 @@ class RubyLex
|
|
318
380
|
def check_newline_depth_difference
|
319
381
|
depth_difference = 0
|
320
382
|
open_brace_on_line = 0
|
383
|
+
in_oneliner_def = nil
|
321
384
|
@tokens.each_with_index do |t, index|
|
385
|
+
# detecting one-liner method definition
|
386
|
+
if in_oneliner_def.nil?
|
387
|
+
if t[3].allbits?(Ripper::EXPR_ENDFN)
|
388
|
+
in_oneliner_def = :ENDFN
|
389
|
+
end
|
390
|
+
else
|
391
|
+
if t[3].allbits?(Ripper::EXPR_ENDFN)
|
392
|
+
# continuing
|
393
|
+
elsif t[3].allbits?(Ripper::EXPR_BEG)
|
394
|
+
if t[2] == '='
|
395
|
+
in_oneliner_def = :BODY
|
396
|
+
end
|
397
|
+
else
|
398
|
+
if in_oneliner_def == :BODY
|
399
|
+
# one-liner method definition
|
400
|
+
depth_difference -= 1
|
401
|
+
end
|
402
|
+
in_oneliner_def = nil
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
322
406
|
case t[1]
|
323
407
|
when :on_ignored_nl, :on_nl, :on_comment
|
324
408
|
if index != (@tokens.size - 1)
|
@@ -330,7 +414,7 @@ class RubyLex
|
|
330
414
|
next
|
331
415
|
end
|
332
416
|
case t[1]
|
333
|
-
when :on_lbracket, :on_lbrace, :on_lparen
|
417
|
+
when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
|
334
418
|
depth_difference += 1
|
335
419
|
open_brace_on_line += 1
|
336
420
|
when :on_rbracket, :on_rbrace, :on_rparen
|
@@ -349,12 +433,12 @@ class RubyLex
|
|
349
433
|
end
|
350
434
|
when 'def', 'case', 'for', 'begin', 'class', 'module'
|
351
435
|
depth_difference += 1
|
352
|
-
when 'if', 'unless', 'while', 'until'
|
436
|
+
when 'if', 'unless', 'while', 'until', 'rescue'
|
353
437
|
# postfix if/unless/while/until/rescue must be Ripper::EXPR_LABEL
|
354
438
|
unless t[3].allbits?(Ripper::EXPR_LABEL)
|
355
439
|
depth_difference += 1
|
356
440
|
end
|
357
|
-
when 'else', 'elsif', '
|
441
|
+
when 'else', 'elsif', 'ensure', 'when', 'in'
|
358
442
|
depth_difference += 1
|
359
443
|
end
|
360
444
|
end
|
@@ -369,7 +453,34 @@ class RubyLex
|
|
369
453
|
spaces_of_nest = []
|
370
454
|
spaces_at_line_head = 0
|
371
455
|
open_brace_on_line = 0
|
456
|
+
in_oneliner_def = nil
|
372
457
|
@tokens.each_with_index do |t, index|
|
458
|
+
# detecting one-liner method definition
|
459
|
+
if in_oneliner_def.nil?
|
460
|
+
if t[3].allbits?(Ripper::EXPR_ENDFN)
|
461
|
+
in_oneliner_def = :ENDFN
|
462
|
+
end
|
463
|
+
else
|
464
|
+
if t[3].allbits?(Ripper::EXPR_ENDFN)
|
465
|
+
# continuing
|
466
|
+
elsif t[3].allbits?(Ripper::EXPR_BEG)
|
467
|
+
if t[2] == '='
|
468
|
+
in_oneliner_def = :BODY
|
469
|
+
end
|
470
|
+
else
|
471
|
+
if in_oneliner_def == :BODY
|
472
|
+
# one-liner method definition
|
473
|
+
if is_first_printable_of_line
|
474
|
+
corresponding_token_depth = spaces_of_nest.pop
|
475
|
+
else
|
476
|
+
spaces_of_nest.pop
|
477
|
+
corresponding_token_depth = nil
|
478
|
+
end
|
479
|
+
end
|
480
|
+
in_oneliner_def = nil
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
373
484
|
case t[1]
|
374
485
|
when :on_ignored_nl, :on_nl, :on_comment
|
375
486
|
corresponding_token_depth = nil
|
@@ -384,7 +495,7 @@ class RubyLex
|
|
384
495
|
next
|
385
496
|
end
|
386
497
|
case t[1]
|
387
|
-
when :on_lbracket, :on_lbrace, :on_lparen
|
498
|
+
when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
|
388
499
|
spaces_of_nest.push(spaces_at_line_head + open_brace_on_line * 2)
|
389
500
|
open_brace_on_line += 1
|
390
501
|
when :on_rbracket, :on_rbrace, :on_rparen
|
@@ -400,12 +511,16 @@ class RubyLex
|
|
400
511
|
case t[2]
|
401
512
|
when 'def', 'do', 'case', 'for', 'begin', 'class', 'module'
|
402
513
|
spaces_of_nest.push(spaces_at_line_head)
|
514
|
+
when 'rescue'
|
515
|
+
unless t[3].allbits?(Ripper::EXPR_LABEL)
|
516
|
+
corresponding_token_depth = spaces_of_nest.last
|
517
|
+
end
|
403
518
|
when 'if', 'unless', 'while', 'until'
|
404
|
-
# postfix if/unless/while/until
|
519
|
+
# postfix if/unless/while/until must be Ripper::EXPR_LABEL
|
405
520
|
unless t[3].allbits?(Ripper::EXPR_LABEL)
|
406
521
|
spaces_of_nest.push(spaces_at_line_head)
|
407
522
|
end
|
408
|
-
when 'else', 'elsif', '
|
523
|
+
when 'else', 'elsif', 'ensure', 'when', 'in'
|
409
524
|
corresponding_token_depth = spaces_of_nest.last
|
410
525
|
when 'end'
|
411
526
|
if is_first_printable_of_line
|
@@ -422,12 +537,12 @@ class RubyLex
|
|
422
537
|
corresponding_token_depth
|
423
538
|
end
|
424
539
|
|
425
|
-
def check_string_literal
|
540
|
+
def check_string_literal(tokens)
|
426
541
|
i = 0
|
427
542
|
start_token = []
|
428
543
|
end_type = []
|
429
|
-
while i <
|
430
|
-
t =
|
544
|
+
while i < tokens.size
|
545
|
+
t = tokens[i]
|
431
546
|
case t[1]
|
432
547
|
when :on_tstring_beg
|
433
548
|
start_token << t
|
@@ -437,7 +552,7 @@ class RubyLex
|
|
437
552
|
end_type << :on_regexp_end
|
438
553
|
when :on_symbeg
|
439
554
|
acceptable_single_tokens = %i{on_ident on_const on_op on_cvar on_ivar on_gvar on_kw}
|
440
|
-
if (i + 1) <
|
555
|
+
if (i + 1) < tokens.size and acceptable_single_tokens.all?{ |t| tokens[i + 1][1] != t }
|
441
556
|
start_token << t
|
442
557
|
end_type << :on_tstring_end
|
443
558
|
end
|
@@ -459,8 +574,8 @@ class RubyLex
|
|
459
574
|
start_token.last.nil? ? '' : start_token.last
|
460
575
|
end
|
461
576
|
|
462
|
-
def process_literal_type
|
463
|
-
start_token = check_string_literal
|
577
|
+
def process_literal_type(tokens)
|
578
|
+
start_token = check_string_literal(tokens)
|
464
579
|
case start_token[1]
|
465
580
|
when :on_tstring_beg
|
466
581
|
case start_token[2]
|
data/lib/irb/ruby_logo.aa
CHANGED
data/lib/irb/version.rb
CHANGED
data/lib/irb/workspace.rb
CHANGED
@@ -51,11 +51,13 @@ EOF
|
|
51
51
|
end
|
52
52
|
@binding = BINDING_QUEUE.pop
|
53
53
|
|
54
|
-
when 3 # binding in function on TOPLEVEL_BINDING
|
55
|
-
@binding = eval("self.class.
|
54
|
+
when 3 # binding in function on TOPLEVEL_BINDING
|
55
|
+
@binding = eval("self.class.remove_method(:irb_binding) if defined?(irb_binding); private; def irb_binding; binding; end; irb_binding",
|
56
56
|
TOPLEVEL_BINDING,
|
57
57
|
__FILE__,
|
58
58
|
__LINE__ - 3)
|
59
|
+
when 4 # binding is a copy of TOPLEVEL_BINDING (default)
|
60
|
+
@binding = TOPLEVEL_BINDING.dup
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
data/lib/irb/xmp.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.2.
|
4
|
+
version: 1.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keiju ISHITSUKA
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: reline
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.1.5
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.1.5
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,9 +116,10 @@ files:
|
|
116
116
|
- man/irb.1
|
117
117
|
homepage: https://github.com/ruby/irb
|
118
118
|
licenses:
|
119
|
+
- Ruby
|
119
120
|
- BSD-2-Clause
|
120
121
|
metadata: {}
|
121
|
-
post_install_message:
|
122
|
+
post_install_message:
|
122
123
|
rdoc_options: []
|
123
124
|
require_paths:
|
124
125
|
- lib
|
@@ -133,8 +134,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
134
|
- !ruby/object:Gem::Version
|
134
135
|
version: '0'
|
135
136
|
requirements: []
|
136
|
-
rubygems_version: 3.1.
|
137
|
-
signing_key:
|
137
|
+
rubygems_version: 3.1.4
|
138
|
+
signing_key:
|
138
139
|
specification_version: 4
|
139
140
|
summary: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).
|
140
141
|
test_files: []
|