irb 1.3.5 → 1.3.8.pre.2
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/Gemfile +10 -0
- data/Rakefile +1 -1
- data/doc/irb/irb.rd.ja +2 -0
- data/irb.gemspec +1 -3
- data/lib/irb/cmd/info.rb +6 -0
- data/lib/irb/cmd/ls.rb +20 -2
- data/lib/irb/cmd/measure.rb +3 -0
- data/lib/irb/cmd/show_source.rb +13 -3
- data/lib/irb/color.rb +9 -14
- data/lib/irb/context.rb +5 -0
- data/lib/irb/init.rb +21 -4
- data/lib/irb/input-method.rb +49 -0
- data/lib/irb/lc/help-message +2 -0
- data/lib/irb/lc/ja/help-message +2 -0
- data/lib/irb/ruby-lex.rb +34 -19
- data/lib/irb/version.rb +2 -2
- data/lib/irb.rb +15 -5
- data/man/irb.1 +8 -0
- metadata +7 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6917cc502c36eee80046354a84e97d8584ab167edc657871f04c7f7a70491601
|
4
|
+
data.tar.gz: 3dedb3a1d6fab3a6cafd09a033ae76f6bbf982e18a886390dbb90b1c91d12180
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a273f5107f23d828fdf485c5c58b110f6e066f3b020dacf5e7c7d8d751eb57e4e573f4026eb7be0494125d6a2665e1a1a13c53400ac50358645cfcec34e49f5
|
7
|
+
data.tar.gz: d7f30a0664d8adec1656348706c02b8ceca27194a01f6de760b9f39c051e98eccb1891bd84cf3add8dbef7575023c877b47f9301274e80af6a776f83e77071ee
|
data/Gemfile
CHANGED
@@ -3,3 +3,13 @@ source "https://rubygems.org"
|
|
3
3
|
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
4
4
|
|
5
5
|
gemspec
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem "bundler"
|
9
|
+
is_unix = RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
|
10
|
+
is_truffleruby = RUBY_DESCRIPTION =~ /truffleruby/
|
11
|
+
gem 'vterm', '>= 0.0.5' if is_unix && ENV['WITH_VTERM']
|
12
|
+
gem 'yamatanooroti', '>= 0.0.6'
|
13
|
+
gem "rake"
|
14
|
+
gem "stackprof" if is_unix && !is_truffleruby
|
15
|
+
end
|
data/Rakefile
CHANGED
data/doc/irb/irb.rd.ja
CHANGED
data/irb.gemspec
CHANGED
@@ -36,7 +36,5 @@ Gem::Specification.new do |spec|
|
|
36
36
|
|
37
37
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.5")
|
38
38
|
|
39
|
-
spec.add_dependency "reline", ">= 0.
|
40
|
-
spec.add_development_dependency "bundler"
|
41
|
-
spec.add_development_dependency "rake"
|
39
|
+
spec.add_dependency "reline", ">= 0.2.8.pre.3"
|
42
40
|
end
|
data/lib/irb/cmd/info.rb
CHANGED
@@ -14,6 +14,12 @@ module IRB
|
|
14
14
|
str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
|
15
15
|
str += ".irbrc path: #{IRB.rc_file}\n" if File.exist?(IRB.rc_file)
|
16
16
|
str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
|
17
|
+
str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty?
|
18
|
+
str += "LC_ALL env: #{ENV["LC_ALL"]}\n" if ENV["LC_ALL"] && !ENV["LC_ALL"].empty?
|
19
|
+
if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
20
|
+
codepage = `chcp`.sub(/.*: (\d+)\n/, '\1')
|
21
|
+
str += "Code page: #{codepage}\n"
|
22
|
+
end
|
17
23
|
str
|
18
24
|
end
|
19
25
|
alias_method :to_s, :inspect
|
data/lib/irb/cmd/ls.rb
CHANGED
@@ -16,13 +16,31 @@ module IRB
|
|
16
16
|
klass = (obj.class == Class || obj.class == Module ? obj : obj.class)
|
17
17
|
|
18
18
|
o.dump("constants", obj.constants) if obj.respond_to?(:constants)
|
19
|
-
o
|
20
|
-
o.dump("#{klass}#methods", klass.public_instance_methods(false))
|
19
|
+
dump_methods(o, klass, obj)
|
21
20
|
o.dump("instance variables", obj.instance_variables)
|
22
21
|
o.dump("class variables", klass.class_variables)
|
23
22
|
o.dump("locals", locals)
|
24
23
|
end
|
25
24
|
|
25
|
+
def dump_methods(o, klass, obj)
|
26
|
+
singleton_class = begin obj.singleton_class; rescue TypeError; nil end
|
27
|
+
maps = class_method_map((singleton_class || klass).ancestors)
|
28
|
+
maps.each do |mod, methods|
|
29
|
+
name = mod == singleton_class ? "#{klass}.methods" : "#{mod}#methods"
|
30
|
+
o.dump(name, methods)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def class_method_map(classes)
|
35
|
+
dumped = Array.new
|
36
|
+
classes.reject { |mod| mod >= Object }.map do |mod|
|
37
|
+
methods = mod.public_instance_methods(false).select do |m|
|
38
|
+
dumped.push(m) unless dumped.include?(m)
|
39
|
+
end
|
40
|
+
[mod, methods]
|
41
|
+
end.reverse
|
42
|
+
end
|
43
|
+
|
26
44
|
class Output
|
27
45
|
MARGIN = " "
|
28
46
|
|
data/lib/irb/cmd/measure.rb
CHANGED
@@ -9,6 +9,9 @@ module IRB
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def execute(type = nil, arg = nil, &block)
|
12
|
+
# Please check IRB.init_config in lib/irb/init.rb that sets
|
13
|
+
# IRB.conf[:MEASURE_PROC] to register default "measure" methods,
|
14
|
+
# "measure :time" (abbreviated as "measure") and "measure :stackprof".
|
12
15
|
case type
|
13
16
|
when :off
|
14
17
|
IRB.conf[:MEASURE] = nil
|
data/lib/irb/cmd/show_source.rb
CHANGED
@@ -59,11 +59,21 @@ module IRB
|
|
59
59
|
def find_end(file, first_line)
|
60
60
|
return first_line unless File.exist?(file)
|
61
61
|
lex = RubyLex.new
|
62
|
+
lines = File.read(file).lines[(first_line - 1)..-1]
|
63
|
+
tokens = RubyLex.ripper_lex_without_warning(lines.join)
|
64
|
+
|
62
65
|
code = +""
|
63
|
-
|
64
|
-
|
66
|
+
prev_tokens = []
|
67
|
+
|
68
|
+
# chunk with line number
|
69
|
+
tokens.chunk { |tok| tok[0][0] }.each do |lnum, chunk|
|
70
|
+
code << lines[lnum]
|
71
|
+
prev_tokens.concat chunk
|
72
|
+
|
73
|
+
continue = lex.process_continue(prev_tokens)
|
74
|
+
code_block_open = lex.check_code_block(code, prev_tokens)
|
65
75
|
if !continue && !code_block_open
|
66
|
-
return first_line +
|
76
|
+
return first_line + lnum
|
67
77
|
end
|
68
78
|
end
|
69
79
|
first_line
|
data/lib/irb/color.rb
CHANGED
@@ -77,7 +77,7 @@ module IRB # :nodoc:
|
|
77
77
|
|
78
78
|
class << self
|
79
79
|
def colorable?
|
80
|
-
$stdout.tty? &&
|
80
|
+
$stdout.tty? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
|
81
81
|
end
|
82
82
|
|
83
83
|
def inspect_colorable?(obj, seen: {}.compare_by_identity)
|
@@ -101,22 +101,22 @@ module IRB # :nodoc:
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
104
|
-
def clear
|
105
|
-
return '' unless colorable
|
104
|
+
def clear(colorable: colorable?)
|
105
|
+
return '' unless colorable
|
106
106
|
"\e[#{CLEAR}m"
|
107
107
|
end
|
108
108
|
|
109
|
-
def colorize(text, seq)
|
110
|
-
return text unless colorable
|
109
|
+
def colorize(text, seq, colorable: colorable?)
|
110
|
+
return text unless colorable
|
111
111
|
seq = seq.map { |s| "\e[#{const_get(s)}m" }.join('')
|
112
|
-
"#{seq}#{text}#{clear}"
|
112
|
+
"#{seq}#{text}#{clear(colorable: colorable)}"
|
113
113
|
end
|
114
114
|
|
115
115
|
# If `complete` is false (code is incomplete), this does not warn compile_error.
|
116
116
|
# This option is needed to avoid warning a user when the compile_error is happening
|
117
117
|
# because the input is not wrong but just incomplete.
|
118
|
-
def colorize_code(code, complete: true, ignore_error: false)
|
119
|
-
return code unless colorable
|
118
|
+
def colorize_code(code, complete: true, ignore_error: false, colorable: colorable?)
|
119
|
+
return code unless colorable
|
120
120
|
|
121
121
|
symbol_state = SymbolState.new
|
122
122
|
colored = +''
|
@@ -134,7 +134,7 @@ module IRB # :nodoc:
|
|
134
134
|
line = Reline::Unicode.escape_for_print(line)
|
135
135
|
if seq = dispatch_seq(token, expr, line, in_symbol: in_symbol)
|
136
136
|
colored << seq.map { |s| "\e[#{s}m" }.join('')
|
137
|
-
colored << line.sub(/\Z/, clear)
|
137
|
+
colored << line.sub(/\Z/, clear(colorable: colorable))
|
138
138
|
else
|
139
139
|
colored << line
|
140
140
|
end
|
@@ -161,11 +161,6 @@ module IRB # :nodoc:
|
|
161
161
|
seen.delete(obj)
|
162
162
|
end
|
163
163
|
|
164
|
-
def supported?
|
165
|
-
return @supported if defined?(@supported)
|
166
|
-
@supported = Ripper::Lexer::Elem.method_defined?(:state)
|
167
|
-
end
|
168
|
-
|
169
164
|
def scan(code, allow_last_error:)
|
170
165
|
pos = [1, 0]
|
171
166
|
|
data/lib/irb/context.rb
CHANGED
@@ -54,6 +54,7 @@ module IRB
|
|
54
54
|
@use_multiline = nil
|
55
55
|
end
|
56
56
|
@use_colorize = IRB.conf[:USE_COLORIZE]
|
57
|
+
@use_autocomplete = IRB.conf[:USE_AUTOCOMPLETE]
|
57
58
|
@verbose = IRB.conf[:VERBOSE]
|
58
59
|
@io = nil
|
59
60
|
|
@@ -185,6 +186,8 @@ module IRB
|
|
185
186
|
#
|
186
187
|
# A copy of the default <code>IRB.conf[:USE_COLORIZE]</code>
|
187
188
|
attr_reader :use_colorize
|
189
|
+
# A copy of the default <code>IRB.conf[:USE_AUTOCOMPLETE]</code>
|
190
|
+
attr_reader :use_autocomplete
|
188
191
|
# A copy of the default <code>IRB.conf[:INSPECT_MODE]</code>
|
189
192
|
attr_reader :inspect_mode
|
190
193
|
|
@@ -311,6 +314,8 @@ module IRB
|
|
311
314
|
alias use_readline? use_singleline
|
312
315
|
# Alias for #use_colorize
|
313
316
|
alias use_colorize? use_colorize
|
317
|
+
# Alias for #use_autocomplete
|
318
|
+
alias use_autocomplete? use_autocomplete
|
314
319
|
# Alias for #rc
|
315
320
|
alias rc? rc
|
316
321
|
alias ignore_sigint? ignore_sigint
|
data/lib/irb/init.rb
CHANGED
@@ -44,7 +44,8 @@ module IRB # :nodoc:
|
|
44
44
|
@CONF[:IRB_RC] = nil
|
45
45
|
|
46
46
|
@CONF[:USE_SINGLELINE] = false unless defined?(ReadlineInputMethod)
|
47
|
-
@CONF[:USE_COLORIZE] =
|
47
|
+
@CONF[:USE_COLORIZE] = !ENV['NO_COLOR']
|
48
|
+
@CONF[:USE_AUTOCOMPLETE] = true
|
48
49
|
@CONF[:INSPECT_MODE] = true
|
49
50
|
@CONF[:USE_TRACER] = false
|
50
51
|
@CONF[:USE_LOADER] = false
|
@@ -120,7 +121,11 @@ module IRB # :nodoc:
|
|
120
121
|
puts 'processing time: %fs' % (now - time) if IRB.conf[:MEASURE]
|
121
122
|
result
|
122
123
|
}
|
124
|
+
# arg can be either a symbol for the mode (:cpu, :wall, ..) or a hash for
|
125
|
+
# a more complete configuration.
|
126
|
+
# See https://github.com/tmm1/stackprof#all-options.
|
123
127
|
@CONF[:MEASURE_PROC][:STACKPROF] = proc { |context, code, line_no, arg, &block|
|
128
|
+
return block.() unless IRB.conf[:MEASURE]
|
124
129
|
success = false
|
125
130
|
begin
|
126
131
|
require 'stackprof'
|
@@ -130,10 +135,18 @@ module IRB # :nodoc:
|
|
130
135
|
end
|
131
136
|
if success
|
132
137
|
result = nil
|
133
|
-
|
138
|
+
arg = { mode: arg || :cpu } unless arg.is_a?(Hash)
|
139
|
+
stackprof_result = StackProf.run(**arg) do
|
134
140
|
result = block.()
|
135
141
|
end
|
136
|
-
|
142
|
+
case stackprof_result
|
143
|
+
when File
|
144
|
+
puts "StackProf report saved to #{stackprof_result.path}"
|
145
|
+
when Hash
|
146
|
+
StackProf::Report.new(stackprof_result).print_text
|
147
|
+
else
|
148
|
+
puts "Stackprof ran with #{arg.inspect}"
|
149
|
+
end
|
137
150
|
result
|
138
151
|
else
|
139
152
|
block.()
|
@@ -262,6 +275,10 @@ module IRB # :nodoc:
|
|
262
275
|
@CONF[:USE_COLORIZE] = true
|
263
276
|
when "--nocolorize"
|
264
277
|
@CONF[:USE_COLORIZE] = false
|
278
|
+
when "--autocomplete"
|
279
|
+
@CONF[:USE_AUTOCOMPLETE] = true
|
280
|
+
when "--noautocomplete"
|
281
|
+
@CONF[:USE_AUTOCOMPLETE] = false
|
265
282
|
when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/
|
266
283
|
opt = $1 || argv.shift
|
267
284
|
prompt_mode = opt.upcase.tr("-", "_").intern
|
@@ -301,11 +318,11 @@ module IRB # :nodoc:
|
|
301
318
|
break
|
302
319
|
end
|
303
320
|
end
|
321
|
+
|
304
322
|
load_path.collect! do |path|
|
305
323
|
/\A\.\// =~ path ? path : File.expand_path(path)
|
306
324
|
end
|
307
325
|
$LOAD_PATH.unshift(*load_path)
|
308
|
-
|
309
326
|
end
|
310
327
|
|
311
328
|
# running config
|
data/lib/irb/input-method.rb
CHANGED
@@ -14,6 +14,7 @@ require_relative 'magic-file'
|
|
14
14
|
require_relative 'completion'
|
15
15
|
require 'io/console'
|
16
16
|
require 'reline'
|
17
|
+
require 'rdoc'
|
17
18
|
|
18
19
|
module IRB
|
19
20
|
STDIN_FILE_NAME = "(line)" # :nodoc:
|
@@ -294,6 +295,10 @@ module IRB
|
|
294
295
|
end
|
295
296
|
end
|
296
297
|
Reline.dig_perfect_match_proc = IRB::InputCompletor::PerfectMatchedProc
|
298
|
+
Reline.autocompletion = IRB.conf[:USE_AUTOCOMPLETE]
|
299
|
+
if IRB.conf[:USE_AUTOCOMPLETE]
|
300
|
+
Reline.add_dialog_proc(:show_doc, SHOW_DOC_DIALOG, Reline::DEFAULT_DIALOG_CONTEXT)
|
301
|
+
end
|
297
302
|
end
|
298
303
|
|
299
304
|
def check_termination(&block)
|
@@ -308,6 +313,50 @@ module IRB
|
|
308
313
|
@auto_indent_proc = block
|
309
314
|
end
|
310
315
|
|
316
|
+
SHOW_DOC_DIALOG = ->() {
|
317
|
+
begin
|
318
|
+
require 'rdoc'
|
319
|
+
rescue LoadError
|
320
|
+
return nil
|
321
|
+
end
|
322
|
+
if just_cursor_moving and completion_journey_data.nil?
|
323
|
+
return nil
|
324
|
+
end
|
325
|
+
cursor_pos_to_render, result, pointer = context.pop(3)
|
326
|
+
return nil if result.nil? or pointer.nil?
|
327
|
+
name = result[pointer]
|
328
|
+
|
329
|
+
driver = RDoc::RI::Driver.new
|
330
|
+
begin
|
331
|
+
name = driver.expand_name(name)
|
332
|
+
rescue RDoc::RI::Driver::NotFoundError
|
333
|
+
return nil
|
334
|
+
end
|
335
|
+
doc = nil
|
336
|
+
used_for_class = false
|
337
|
+
if not name =~ /#|\./
|
338
|
+
found, klasses, includes, extends = driver.classes_and_includes_and_extends_for(name)
|
339
|
+
if not found.empty?
|
340
|
+
doc = driver.class_document(name, found, klasses, includes, extends)
|
341
|
+
used_for_class = true
|
342
|
+
end
|
343
|
+
end
|
344
|
+
unless used_for_class
|
345
|
+
doc = RDoc::Markup::Document.new
|
346
|
+
begin
|
347
|
+
driver.add_method(doc, name)
|
348
|
+
rescue RDoc::RI::Driver::NotFoundError
|
349
|
+
doc = nil
|
350
|
+
end
|
351
|
+
end
|
352
|
+
return nil if doc.nil?
|
353
|
+
formatter = RDoc::Markup::ToAnsi.new
|
354
|
+
formatter.width = 40
|
355
|
+
str = doc.accept(formatter)
|
356
|
+
|
357
|
+
[Reline::CursorPos.new(cursor_pos_to_render.x + 40, cursor_pos_to_render.y + pointer), str.split("\n"), nil, '49']
|
358
|
+
}
|
359
|
+
|
311
360
|
# Reads the next line from this input method.
|
312
361
|
#
|
313
362
|
# See IO#gets for more information.
|
data/lib/irb/lc/help-message
CHANGED
@@ -30,6 +30,8 @@ Usage: irb.rb [options] [programfile] [arguments]
|
|
30
30
|
--nosingleline Don't use singleline editor module
|
31
31
|
--colorize Use colorization
|
32
32
|
--nocolorize Don't use colorization
|
33
|
+
--autocomplete Use autocompletion
|
34
|
+
--noautocomplete Don't use autocompletion
|
33
35
|
--prompt prompt-mode/--prompt-mode prompt-mode
|
34
36
|
Switch prompt mode. Pre-defined prompt modes are
|
35
37
|
`default', `simple', `xmp' and `inf-ruby'
|
data/lib/irb/lc/ja/help-message
CHANGED
@@ -29,6 +29,8 @@ Usage: irb.rb [options] [programfile] [arguments]
|
|
29
29
|
--nosingleline シングルラインエディタを利用しない.
|
30
30
|
--colorize 色付けを利用する.
|
31
31
|
--nocolorize 色付けを利用しない.
|
32
|
+
--autocomplete オートコンプリートを利用する.
|
33
|
+
--noautocomplete オートコンプリートを利用しない.
|
32
34
|
--prompt prompt-mode/--prompt-mode prompt-mode
|
33
35
|
プロンプトモードを切替えます. 現在定義されているプ
|
34
36
|
ロンプトモードは, default, simple, xmp, inf-rubyが
|
data/lib/irb/ruby-lex.rb
CHANGED
@@ -30,26 +30,31 @@ class RubyLex
|
|
30
30
|
@prompt = nil
|
31
31
|
end
|
32
32
|
|
33
|
-
def self.compile_with_errors_suppressed(code)
|
34
|
-
line_no = 1
|
33
|
+
def self.compile_with_errors_suppressed(code, line_no: 1)
|
35
34
|
begin
|
36
35
|
result = yield code, line_no
|
37
36
|
rescue ArgumentError
|
37
|
+
# Ruby can issue an error for the code if there is an
|
38
|
+
# incomplete magic comment for encoding in it. Force an
|
39
|
+
# expression with a new line before the code in this
|
40
|
+
# case to prevent magic comment handling. To make sure
|
41
|
+
# line numbers in the lexed code remain the same,
|
42
|
+
# decrease the line number by one.
|
38
43
|
code = ";\n#{code}"
|
39
|
-
line_no
|
44
|
+
line_no -= 1
|
40
45
|
result = yield code, line_no
|
41
46
|
end
|
42
47
|
result
|
43
48
|
end
|
44
49
|
|
45
50
|
# io functions
|
46
|
-
def set_input(io, p = nil, &block)
|
51
|
+
def set_input(io, p = nil, context: nil, &block)
|
47
52
|
@io = io
|
48
53
|
if @io.respond_to?(:check_termination)
|
49
54
|
@io.check_termination do |code|
|
50
55
|
if Reline::IOGate.in_pasting?
|
51
56
|
lex = RubyLex.new
|
52
|
-
rest = lex.check_termination_in_prev_line(code)
|
57
|
+
rest = lex.check_termination_in_prev_line(code, context: context)
|
53
58
|
if rest
|
54
59
|
Reline.delete_text
|
55
60
|
rest.bytes.reverse_each do |c|
|
@@ -61,7 +66,7 @@ class RubyLex
|
|
61
66
|
end
|
62
67
|
else
|
63
68
|
code.gsub!(/\s*\z/, '').concat("\n")
|
64
|
-
ltype, indent, continue, code_block_open = check_state(code)
|
69
|
+
ltype, indent, continue, code_block_open = check_state(code, context: context)
|
65
70
|
if ltype or indent > 0 or continue or code_block_open
|
66
71
|
false
|
67
72
|
else
|
@@ -74,7 +79,7 @@ class RubyLex
|
|
74
79
|
@io.dynamic_prompt do |lines|
|
75
80
|
lines << '' if lines.empty?
|
76
81
|
result = []
|
77
|
-
tokens = self.class.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join)
|
82
|
+
tokens = self.class.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join, context: context)
|
78
83
|
code = String.new
|
79
84
|
partial_tokens = []
|
80
85
|
unprocessed_tokens = []
|
@@ -86,7 +91,7 @@ class RubyLex
|
|
86
91
|
t_str = t[2]
|
87
92
|
t_str.each_line("\n") do |s|
|
88
93
|
code << s << "\n"
|
89
|
-
ltype, indent, continue, code_block_open = check_state(code, partial_tokens)
|
94
|
+
ltype, indent, continue, code_block_open = check_state(code, partial_tokens, context: context)
|
90
95
|
result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
|
91
96
|
line_num_offset += 1
|
92
97
|
end
|
@@ -96,7 +101,7 @@ class RubyLex
|
|
96
101
|
end
|
97
102
|
end
|
98
103
|
unless unprocessed_tokens.empty?
|
99
|
-
ltype, indent, continue, code_block_open = check_state(code, unprocessed_tokens)
|
104
|
+
ltype, indent, continue, code_block_open = check_state(code, unprocessed_tokens, context: context)
|
100
105
|
result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
|
101
106
|
end
|
102
107
|
result
|
@@ -129,15 +134,25 @@ class RubyLex
|
|
129
134
|
:on_param_error
|
130
135
|
]
|
131
136
|
|
132
|
-
def self.ripper_lex_without_warning(code)
|
137
|
+
def self.ripper_lex_without_warning(code, context: nil)
|
133
138
|
verbose, $VERBOSE = $VERBOSE, nil
|
139
|
+
if context
|
140
|
+
lvars = context&.workspace&.binding&.local_variables
|
141
|
+
if lvars && !lvars.empty?
|
142
|
+
code = "#{lvars.join('=')}=nil\n#{code}"
|
143
|
+
line_no = 0
|
144
|
+
else
|
145
|
+
line_no = 1
|
146
|
+
end
|
147
|
+
end
|
134
148
|
tokens = nil
|
135
|
-
compile_with_errors_suppressed(code) do |inner_code, line_no|
|
149
|
+
compile_with_errors_suppressed(code, line_no: line_no) do |inner_code, line_no|
|
136
150
|
lexer = Ripper::Lexer.new(inner_code, '-', line_no)
|
137
151
|
if lexer.respond_to?(:scan) # Ruby 2.7+
|
138
152
|
tokens = []
|
139
153
|
pos_to_index = {}
|
140
154
|
lexer.scan.each do |t|
|
155
|
+
next if t.pos.first == 0
|
141
156
|
if pos_to_index.has_key?(t[0])
|
142
157
|
index = pos_to_index[t[0]]
|
143
158
|
found_tk = tokens[index]
|
@@ -182,7 +197,7 @@ class RubyLex
|
|
182
197
|
if @io.respond_to?(:auto_indent) and context.auto_indent_mode
|
183
198
|
@io.auto_indent do |lines, line_index, byte_pointer, is_newline|
|
184
199
|
if is_newline
|
185
|
-
@tokens = self.class.ripper_lex_without_warning(lines[0..line_index].join("\n"))
|
200
|
+
@tokens = self.class.ripper_lex_without_warning(lines[0..line_index].join("\n"), context: context)
|
186
201
|
prev_spaces = find_prev_spaces(line_index)
|
187
202
|
depth_difference = check_newline_depth_difference
|
188
203
|
depth_difference = 0 if depth_difference < 0
|
@@ -191,7 +206,7 @@ class RubyLex
|
|
191
206
|
code = line_index.zero? ? '' : lines[0..(line_index - 1)].map{ |l| l + "\n" }.join
|
192
207
|
last_line = lines[line_index]&.byteslice(0, byte_pointer)
|
193
208
|
code += last_line if last_line
|
194
|
-
@tokens = self.class.ripper_lex_without_warning(code)
|
209
|
+
@tokens = self.class.ripper_lex_without_warning(code, context: context)
|
195
210
|
corresponding_token_depth = check_corresponding_token_depth
|
196
211
|
if corresponding_token_depth
|
197
212
|
corresponding_token_depth
|
@@ -203,8 +218,8 @@ class RubyLex
|
|
203
218
|
end
|
204
219
|
end
|
205
220
|
|
206
|
-
def check_state(code, tokens = nil)
|
207
|
-
tokens = self.class.ripper_lex_without_warning(code) unless tokens
|
221
|
+
def check_state(code, tokens = nil, context: nil)
|
222
|
+
tokens = self.class.ripper_lex_without_warning(code, context: context) unless tokens
|
208
223
|
ltype = process_literal_type(tokens)
|
209
224
|
indent = process_nesting_level(tokens)
|
210
225
|
continue = process_continue(tokens)
|
@@ -339,7 +354,7 @@ class RubyLex
|
|
339
354
|
# "syntax error, unexpected end-of-input, expecting keyword_end"
|
340
355
|
#
|
341
356
|
# example:
|
342
|
-
# if
|
357
|
+
# if true
|
343
358
|
# hoge
|
344
359
|
# if false
|
345
360
|
# fuga
|
@@ -700,7 +715,7 @@ class RubyLex
|
|
700
715
|
start_token << t
|
701
716
|
end_type << :on_regexp_end
|
702
717
|
when :on_symbeg
|
703
|
-
acceptable_single_tokens = %i{on_ident on_const on_op on_cvar on_ivar on_gvar on_kw}
|
718
|
+
acceptable_single_tokens = %i{on_ident on_const on_op on_cvar on_ivar on_gvar on_kw on_int}
|
704
719
|
if (i + 1) < tokens.size and acceptable_single_tokens.all?{ |st| tokens[i + 1][1] != st }
|
705
720
|
start_token << t
|
706
721
|
end_type << :on_tstring_end
|
@@ -754,8 +769,8 @@ class RubyLex
|
|
754
769
|
end
|
755
770
|
end
|
756
771
|
|
757
|
-
def check_termination_in_prev_line(code)
|
758
|
-
tokens = self.class.ripper_lex_without_warning(code)
|
772
|
+
def check_termination_in_prev_line(code, context: nil)
|
773
|
+
tokens = self.class.ripper_lex_without_warning(code, context: context)
|
759
774
|
past_first_newline = false
|
760
775
|
index = tokens.rindex do |t|
|
761
776
|
# traverse first token before last line
|
data/lib/irb/version.rb
CHANGED
data/lib/irb.rb
CHANGED
@@ -72,6 +72,8 @@ require_relative "irb/easter-egg"
|
|
72
72
|
# --nosingleline Don't use singleline editor module
|
73
73
|
# --colorize Use colorization
|
74
74
|
# --nocolorize Don't use colorization
|
75
|
+
# --autocomplete Use autocompletion
|
76
|
+
# --noautocomplete Don't use autocompletion
|
75
77
|
# --prompt prompt-mode/--prompt-mode prompt-mode
|
76
78
|
# Switch prompt mode. Pre-defined prompt modes are
|
77
79
|
# `default', `simple', `xmp' and `inf-ruby'
|
@@ -114,6 +116,7 @@ require_relative "irb/easter-egg"
|
|
114
116
|
# IRB.conf[:USE_SINGLELINE] = nil
|
115
117
|
# IRB.conf[:USE_COLORIZE] = true
|
116
118
|
# IRB.conf[:USE_TRACER] = false
|
119
|
+
# IRB.conf[:USE_AUTOCOMPLETE] = true
|
117
120
|
# IRB.conf[:IGNORE_SIGINT] = true
|
118
121
|
# IRB.conf[:IGNORE_EOF] = false
|
119
122
|
# IRB.conf[:PROMPT_MODE] = :DEFAULT
|
@@ -524,7 +527,7 @@ module IRB
|
|
524
527
|
@context.io.prompt
|
525
528
|
end
|
526
529
|
|
527
|
-
@scanner.set_input(@context.io) do
|
530
|
+
@scanner.set_input(@context.io, context: @context) do
|
528
531
|
signal_status(:IN_INPUT) do
|
529
532
|
if l = @context.io.gets
|
530
533
|
print l if @context.verbose?
|
@@ -590,9 +593,15 @@ module IRB
|
|
590
593
|
end
|
591
594
|
end
|
592
595
|
|
593
|
-
def convert_invalid_byte_sequence(str)
|
594
|
-
str
|
595
|
-
|
596
|
+
def convert_invalid_byte_sequence(str, enc)
|
597
|
+
str.force_encoding(enc)
|
598
|
+
str.scrub { |c|
|
599
|
+
c.bytes.map{ |b| "\\x#{b.to_s(16).upcase}" }.join
|
600
|
+
}
|
601
|
+
end
|
602
|
+
|
603
|
+
def encode_with_invalid_byte_sequence(str, enc)
|
604
|
+
conv = Encoding::Converter.new(str.encoding, enc)
|
596
605
|
dst = String.new
|
597
606
|
begin
|
598
607
|
ret = conv.primitive_convert(str, dst)
|
@@ -640,7 +649,8 @@ module IRB
|
|
640
649
|
message = exc.full_message(order: :top)
|
641
650
|
order = :top
|
642
651
|
end
|
643
|
-
message = convert_invalid_byte_sequence(message)
|
652
|
+
message = convert_invalid_byte_sequence(message, exc.message.encoding)
|
653
|
+
message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) unless message.encoding.to_s.casecmp?(IRB.conf[:LC_MESSAGES].encoding.to_s)
|
644
654
|
message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
|
645
655
|
case order
|
646
656
|
when :top
|
data/man/irb.1
CHANGED
@@ -18,6 +18,7 @@
|
|
18
18
|
.Op Fl - Ns Oo no Oc Ns singleline
|
19
19
|
.Op Fl - Ns Oo no Oc Ns echo
|
20
20
|
.Op Fl - Ns Oo no Oc Ns colorize
|
21
|
+
.Op Fl - Ns Oo no Oc Ns autocomplete
|
21
22
|
.Op Fl - Ns Oo no Oc Ns verbose
|
22
23
|
.Op Fl -prompt Ar mode
|
23
24
|
.Op Fl -prompt-mode Ar mode
|
@@ -118,6 +119,13 @@ Use colorization.
|
|
118
119
|
Don't use colorization.
|
119
120
|
.Pp
|
120
121
|
.Pp
|
122
|
+
.It Fl -autocomplete
|
123
|
+
Use autocompletion.
|
124
|
+
.Pp
|
125
|
+
.It Fl -noautocomplete
|
126
|
+
Don't use autocompletion.
|
127
|
+
.Pp
|
128
|
+
.Pp
|
121
129
|
.It Fl -verbose
|
122
130
|
Show details.
|
123
131
|
.Pp
|
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.8.pre.2
|
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-
|
11
|
+
date: 2021-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: reline
|
@@ -16,42 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.2.8.pre.3
|
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.
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: bundler
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rake
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
26
|
+
version: 0.2.8.pre.3
|
55
27
|
description: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).
|
56
28
|
email:
|
57
29
|
- keiju@ruby-lang.org
|
@@ -136,11 +108,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
136
108
|
version: '2.5'
|
137
109
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
110
|
requirements:
|
139
|
-
- - "
|
111
|
+
- - ">"
|
140
112
|
- !ruby/object:Gem::Version
|
141
|
-
version:
|
113
|
+
version: 1.3.1
|
142
114
|
requirements: []
|
143
|
-
rubygems_version: 3.
|
115
|
+
rubygems_version: 3.2.22
|
144
116
|
signing_key:
|
145
117
|
specification_version: 4
|
146
118
|
summary: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).
|