irb 1.3.8.pre.8 → 1.4.0
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 +2 -2
- data/doc/irb/irb.rd.ja +6 -0
- data/irb.gemspec +1 -1
- data/lib/irb/cmd/info.rb +2 -1
- data/lib/irb/cmd/show_source.rb +2 -5
- data/lib/irb/completion.rb +44 -12
- data/lib/irb/context.rb +32 -9
- data/lib/irb/init.rb +4 -0
- data/lib/irb/input-method.rb +33 -9
- data/lib/irb/lc/help-message +8 -1
- data/lib/irb/ruby-lex.rb +119 -75
- data/lib/irb/version.rb +2 -2
- data/lib/irb/workspace.rb +3 -0
- data/lib/irb.rb +17 -5
- data/man/irb.1 +15 -1
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6c52cb722e3095862479d2b3238107929c9aacb7d0abdaef02a3ae11ad4d81be
|
|
4
|
+
data.tar.gz: f933953b4a52be77dad05d3f39f4a590f08593c4c29782086c1d59c2f00fc9d5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a6ab46115c8484ec6818876b7a00fd264b3981be71b9a86d0fe4964ea670685ebb6e15bc3d1a6cdc6a0699883088cc75027c77fa67b2f8098c45226d19348f25
|
|
7
|
+
data.tar.gz: 346676856d7c18ad4ac921aa2be2669b988752585ea147283674d614b5646574b7eb7127f9a488e1fe2d1519875674fe18f4daa1179d145fcb333ae2d17b70e0
|
data/Gemfile
CHANGED
|
@@ -5,8 +5,8 @@ gemspec
|
|
|
5
5
|
group :development do
|
|
6
6
|
is_unix = RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
|
|
7
7
|
is_truffleruby = RUBY_DESCRIPTION =~ /truffleruby/
|
|
8
|
-
gem
|
|
9
|
-
gem
|
|
8
|
+
gem "vterm", ">= 0.0.5" if is_unix && ENV['WITH_VTERM']
|
|
9
|
+
gem "yamatanooroti", ">= 0.0.6"
|
|
10
10
|
gem "rake"
|
|
11
11
|
gem "stackprof" if is_unix && !is_truffleruby
|
|
12
12
|
gem "test-unit"
|
data/doc/irb/irb.rd.ja
CHANGED
|
@@ -51,6 +51,12 @@ irbの使い方は, Rubyさえ知っていればいたって簡単です. 基本
|
|
|
51
51
|
オブジェクトの作成方法を 0 から 3 のいずれかに設定する.
|
|
52
52
|
--echo 実行結果を表示する(デフォルト).
|
|
53
53
|
--noecho 実行結果を表示しない.
|
|
54
|
+
--echo-on-assignment
|
|
55
|
+
代入時に実行結果を表示する.
|
|
56
|
+
--noecho-on-assignment
|
|
57
|
+
代入時に実行結果を表示しない.
|
|
58
|
+
--truncate-echo-on-assignment
|
|
59
|
+
代入時に省略された実行結果を表示する(デフォルト).
|
|
54
60
|
--inspect 結果出力にinspectを用いる.
|
|
55
61
|
--noinspect 結果出力にinspectを用いない.
|
|
56
62
|
--singleline シングルラインエディタを利用する.
|
data/irb.gemspec
CHANGED
data/lib/irb/cmd/info.rb
CHANGED
|
@@ -16,8 +16,9 @@ module IRB
|
|
|
16
16
|
str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
|
|
17
17
|
str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty?
|
|
18
18
|
str += "LC_ALL env: #{ENV["LC_ALL"]}\n" if ENV["LC_ALL"] && !ENV["LC_ALL"].empty?
|
|
19
|
+
str += "East Asian Ambiguous Width: #{Reline.ambiguous_width.inspect}\n"
|
|
19
20
|
if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
|
20
|
-
codepage = `chcp`.sub(/.*: (\d+)\n/, '\1')
|
|
21
|
+
codepage = `chcp`.b.sub(/.*: (\d+)\n/, '\1')
|
|
21
22
|
str += "Code page: #{codepage}\n"
|
|
22
23
|
end
|
|
23
24
|
str
|
data/lib/irb/cmd/show_source.rb
CHANGED
|
@@ -61,15 +61,12 @@ module IRB
|
|
|
61
61
|
lex = RubyLex.new
|
|
62
62
|
lines = File.read(file).lines[(first_line - 1)..-1]
|
|
63
63
|
tokens = RubyLex.ripper_lex_without_warning(lines.join)
|
|
64
|
-
|
|
65
|
-
code = +""
|
|
66
64
|
prev_tokens = []
|
|
67
65
|
|
|
68
66
|
# chunk with line number
|
|
69
|
-
tokens.chunk { |tok| tok[0]
|
|
70
|
-
code
|
|
67
|
+
tokens.chunk { |tok| tok.pos[0] }.each do |lnum, chunk|
|
|
68
|
+
code = lines[0..lnum].join
|
|
71
69
|
prev_tokens.concat chunk
|
|
72
|
-
|
|
73
70
|
continue = lex.process_continue(prev_tokens)
|
|
74
71
|
code_block_open = lex.check_code_block(code, prev_tokens)
|
|
75
72
|
if !continue && !code_block_open
|
data/lib/irb/completion.rb
CHANGED
|
@@ -38,16 +38,48 @@ module IRB
|
|
|
38
38
|
|
|
39
39
|
BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
|
|
40
40
|
|
|
41
|
-
def self.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
def self.absolute_path?(p) # TODO Remove this method after 2.6 EOL.
|
|
42
|
+
if File.respond_to?(:absolute_path?)
|
|
43
|
+
File.absolute_path?(p)
|
|
44
|
+
else
|
|
45
|
+
if File.absolute_path(p) == p
|
|
46
|
+
true
|
|
47
|
+
else
|
|
48
|
+
false
|
|
47
49
|
end
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.retrieve_gem_and_system_load_path
|
|
54
|
+
gem_paths = Gem::Specification.latest_specs(true).map { |s|
|
|
55
|
+
s.require_paths.map { |p|
|
|
56
|
+
if absolute_path?(p)
|
|
57
|
+
p
|
|
58
|
+
else
|
|
59
|
+
File.join(s.full_gem_path, p)
|
|
60
|
+
end
|
|
61
|
+
}
|
|
62
|
+
}.flatten if defined?(Gem::Specification)
|
|
63
|
+
(gem_paths.to_a | $LOAD_PATH).sort
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.retrieve_files_to_require_from_load_path
|
|
67
|
+
@@files_from_load_path ||=
|
|
68
|
+
(
|
|
69
|
+
shortest = []
|
|
70
|
+
rest = retrieve_gem_and_system_load_path.each_with_object([]) { |path, result|
|
|
71
|
+
begin
|
|
72
|
+
names = Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: path)
|
|
73
|
+
rescue Errno::ENOENT
|
|
74
|
+
nil
|
|
75
|
+
end
|
|
76
|
+
next if names.empty?
|
|
77
|
+
names.map! { |n| n.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '') }.sort!
|
|
78
|
+
shortest << names.shift
|
|
79
|
+
result.concat(names)
|
|
80
|
+
}
|
|
81
|
+
shortest.sort! | rest
|
|
82
|
+
)
|
|
51
83
|
end
|
|
52
84
|
|
|
53
85
|
def self.retrieve_files_to_require_relative_from_current_dir
|
|
@@ -160,12 +192,12 @@ module IRB
|
|
|
160
192
|
sym = $1
|
|
161
193
|
candidates = Symbol.all_symbols.collect do |s|
|
|
162
194
|
":" + s.id2name.encode(Encoding.default_external)
|
|
163
|
-
rescue
|
|
195
|
+
rescue EncodingError
|
|
164
196
|
# ignore
|
|
165
197
|
end
|
|
166
198
|
candidates.grep(/^#{Regexp.quote(sym)}/)
|
|
167
199
|
|
|
168
|
-
when /^::([A-Z][^:\.\(]*)$/
|
|
200
|
+
when /^::([A-Z][^:\.\(\)]*)$/
|
|
169
201
|
# Absolute Constant or class methods
|
|
170
202
|
receiver = $1
|
|
171
203
|
candidates = Object.constants.collect{|m| m.to_s}
|
|
@@ -258,7 +290,7 @@ module IRB
|
|
|
258
290
|
all_gvars.grep(Regexp.new(Regexp.quote(gvar)))
|
|
259
291
|
end
|
|
260
292
|
|
|
261
|
-
when /^([
|
|
293
|
+
when /^([^.:"].*)(\.|::)([^.]*)$/
|
|
262
294
|
# variable.func or func.func
|
|
263
295
|
receiver = $1
|
|
264
296
|
sep = $2
|
data/lib/irb/context.rb
CHANGED
|
@@ -125,6 +125,8 @@ module IRB
|
|
|
125
125
|
end
|
|
126
126
|
self.save_history = IRB.conf[:SAVE_HISTORY] if IRB.conf[:SAVE_HISTORY]
|
|
127
127
|
|
|
128
|
+
@extra_doc_dirs = IRB.conf[:EXTRA_DOC_DIRS]
|
|
129
|
+
|
|
128
130
|
@echo = IRB.conf[:ECHO]
|
|
129
131
|
if @echo.nil?
|
|
130
132
|
@echo = true
|
|
@@ -148,18 +150,18 @@ module IRB
|
|
|
148
150
|
|
|
149
151
|
# The toplevel workspace, see #home_workspace
|
|
150
152
|
attr_reader :workspace_home
|
|
151
|
-
# WorkSpace in the current context
|
|
153
|
+
# WorkSpace in the current context.
|
|
152
154
|
attr_accessor :workspace
|
|
153
|
-
# The current thread in this context
|
|
155
|
+
# The current thread in this context.
|
|
154
156
|
attr_reader :thread
|
|
155
|
-
# The current input method
|
|
157
|
+
# The current input method.
|
|
156
158
|
#
|
|
157
159
|
# Can be either StdioInputMethod, ReadlineInputMethod,
|
|
158
160
|
# ReidlineInputMethod, FileInputMethod or other specified when the
|
|
159
161
|
# context is created. See ::new for more # information on +input_method+.
|
|
160
162
|
attr_accessor :io
|
|
161
163
|
|
|
162
|
-
# Current irb session
|
|
164
|
+
# Current irb session.
|
|
163
165
|
attr_accessor :irb
|
|
164
166
|
# A copy of the default <code>IRB.conf[:AP_NAME]</code>
|
|
165
167
|
attr_accessor :ap_name
|
|
@@ -193,15 +195,15 @@ module IRB
|
|
|
193
195
|
|
|
194
196
|
# A copy of the default <code>IRB.conf[:PROMPT_MODE]</code>
|
|
195
197
|
attr_reader :prompt_mode
|
|
196
|
-
# Standard IRB prompt
|
|
198
|
+
# Standard IRB prompt.
|
|
197
199
|
#
|
|
198
200
|
# See IRB@Customizing+the+IRB+Prompt for more information.
|
|
199
201
|
attr_accessor :prompt_i
|
|
200
|
-
# IRB prompt for continuated strings
|
|
202
|
+
# IRB prompt for continuated strings.
|
|
201
203
|
#
|
|
202
204
|
# See IRB@Customizing+the+IRB+Prompt for more information.
|
|
203
205
|
attr_accessor :prompt_s
|
|
204
|
-
# IRB prompt for continuated statement (e.g. immediately after an +if+)
|
|
206
|
+
# IRB prompt for continuated statement. (e.g. immediately after an +if+)
|
|
205
207
|
#
|
|
206
208
|
# See IRB@Customizing+the+IRB+Prompt for more information.
|
|
207
209
|
attr_accessor :prompt_c
|
|
@@ -241,6 +243,9 @@ module IRB
|
|
|
241
243
|
#
|
|
242
244
|
# If set to +false+, <code>^D</code> will quit irb.
|
|
243
245
|
attr_accessor :ignore_eof
|
|
246
|
+
# Specify the installation locations of the ri file to be displayed in the
|
|
247
|
+
# document dialog.
|
|
248
|
+
attr_accessor :extra_doc_dirs
|
|
244
249
|
# Whether to echo the return value to output or not.
|
|
245
250
|
#
|
|
246
251
|
# Uses <code>IRB.conf[:ECHO]</code> if available, or defaults to +true+.
|
|
@@ -252,7 +257,7 @@ module IRB
|
|
|
252
257
|
# puts "omg"
|
|
253
258
|
# # omg
|
|
254
259
|
attr_accessor :echo
|
|
255
|
-
# Whether to echo for assignment expressions
|
|
260
|
+
# Whether to echo for assignment expressions.
|
|
256
261
|
#
|
|
257
262
|
# If set to +false+, the value of assignment will not be shown.
|
|
258
263
|
#
|
|
@@ -264,13 +269,28 @@ module IRB
|
|
|
264
269
|
#
|
|
265
270
|
# a = "omg"
|
|
266
271
|
# #=> omg
|
|
272
|
+
#
|
|
267
273
|
# a = "omg" * 10
|
|
268
274
|
# #=> omgomgomgomgomgomgomg...
|
|
275
|
+
#
|
|
269
276
|
# IRB.CurrentContext.echo_on_assignment = false
|
|
270
277
|
# a = "omg"
|
|
278
|
+
#
|
|
271
279
|
# IRB.CurrentContext.echo_on_assignment = true
|
|
272
|
-
# a = "omg"
|
|
280
|
+
# a = "omg" * 10
|
|
273
281
|
# #=> omgomgomgomgomgomgomgomgomgomg
|
|
282
|
+
#
|
|
283
|
+
# To set the behaviour of showing on assignment in irb:
|
|
284
|
+
#
|
|
285
|
+
# IRB.conf[:ECHO_ON_ASSIGNMENT] = :truncate or true or false
|
|
286
|
+
#
|
|
287
|
+
# or
|
|
288
|
+
#
|
|
289
|
+
# irb_context.echo_on_assignment = :truncate or true or false
|
|
290
|
+
#
|
|
291
|
+
# or
|
|
292
|
+
#
|
|
293
|
+
# IRB.CurrentContext.echo_on_assignment = :truncate or true or false
|
|
274
294
|
attr_accessor :echo_on_assignment
|
|
275
295
|
# Whether a newline is put before multiline output.
|
|
276
296
|
#
|
|
@@ -371,6 +391,7 @@ module IRB
|
|
|
371
391
|
@prompt_c = pconf[:PROMPT_C]
|
|
372
392
|
@prompt_n = pconf[:PROMPT_N]
|
|
373
393
|
@return_format = pconf[:RETURN]
|
|
394
|
+
@return_format = "%s\n" if @return_format == nil
|
|
374
395
|
if ai = pconf.include?(:AUTO_INDENT)
|
|
375
396
|
@auto_indent_mode = ai
|
|
376
397
|
else
|
|
@@ -463,6 +484,8 @@ module IRB
|
|
|
463
484
|
# Exits the current session, see IRB.irb_exit
|
|
464
485
|
def exit(ret = 0)
|
|
465
486
|
IRB.irb_exit(@irb, ret)
|
|
487
|
+
rescue UncaughtThrowError
|
|
488
|
+
super
|
|
466
489
|
end
|
|
467
490
|
|
|
468
491
|
NOPRINTING_IVARS = ["@last_value"] # :nodoc:
|
data/lib/irb/init.rb
CHANGED
|
@@ -51,6 +51,7 @@ module IRB # :nodoc:
|
|
|
51
51
|
@CONF[:USE_LOADER] = false
|
|
52
52
|
@CONF[:IGNORE_SIGINT] = true
|
|
53
53
|
@CONF[:IGNORE_EOF] = false
|
|
54
|
+
@CONF[:EXTRA_DOC_DIRS] = []
|
|
54
55
|
@CONF[:ECHO] = nil
|
|
55
56
|
@CONF[:ECHO_ON_ASSIGNMENT] = nil
|
|
56
57
|
@CONF[:VERBOSE] = nil
|
|
@@ -257,6 +258,9 @@ module IRB # :nodoc:
|
|
|
257
258
|
@CONF[:USE_MULTILINE] = true
|
|
258
259
|
when "--nomultiline", "--noreidline"
|
|
259
260
|
@CONF[:USE_MULTILINE] = false
|
|
261
|
+
when /^--extra-doc-dir(?:=(.+))?/
|
|
262
|
+
opt = $1 || argv.shift
|
|
263
|
+
@CONF[:EXTRA_DOC_DIRS] << opt
|
|
260
264
|
when "--echo"
|
|
261
265
|
@CONF[:ECHO] = true
|
|
262
266
|
when "--noecho"
|
data/lib/irb/input-method.rb
CHANGED
|
@@ -265,7 +265,8 @@ module IRB
|
|
|
265
265
|
|
|
266
266
|
class ReidlineInputMethod < InputMethod
|
|
267
267
|
include Reline
|
|
268
|
-
|
|
268
|
+
|
|
269
|
+
# Creates a new input method object using Reline
|
|
269
270
|
def initialize
|
|
270
271
|
IRB.__send__(:set_encoding, Reline.encoding_system_needs.name, override: false)
|
|
271
272
|
super
|
|
@@ -317,13 +318,9 @@ module IRB
|
|
|
317
318
|
dialog.trap_key = nil
|
|
318
319
|
alt_d = [
|
|
319
320
|
[Reline::Key.new(nil, 0xE4, true)], # Normal Alt+d.
|
|
321
|
+
[27, 100], # Normal Alt+d when convert-meta isn't used.
|
|
320
322
|
[195, 164] # The "ä" that appears when Alt+d is pressed on xterm.
|
|
321
323
|
]
|
|
322
|
-
begin
|
|
323
|
-
require 'rdoc'
|
|
324
|
-
rescue LoadError
|
|
325
|
-
return nil
|
|
326
|
-
end
|
|
327
324
|
|
|
328
325
|
if just_cursor_moving and completion_journey_data.nil?
|
|
329
326
|
return nil
|
|
@@ -333,7 +330,9 @@ module IRB
|
|
|
333
330
|
name = result[pointer]
|
|
334
331
|
name = IRB::InputCompletor.retrieve_completion_data(name, doc_namespace: true)
|
|
335
332
|
|
|
336
|
-
|
|
333
|
+
options = {}
|
|
334
|
+
options[:extra_doc_dirs] = IRB.conf[:EXTRA_DOC_DIRS] unless IRB.conf[:EXTRA_DOC_DIRS].empty?
|
|
335
|
+
driver = RDoc::RI::Driver.new(options)
|
|
337
336
|
|
|
338
337
|
if key.match?(dialog.name)
|
|
339
338
|
begin
|
|
@@ -370,14 +369,39 @@ module IRB
|
|
|
370
369
|
end
|
|
371
370
|
return nil if doc.nil?
|
|
372
371
|
width = 40
|
|
372
|
+
|
|
373
|
+
right_x = cursor_pos_to_render.x + autocomplete_dialog.width
|
|
374
|
+
if right_x + width > screen_width
|
|
375
|
+
right_width = screen_width - (right_x + 1)
|
|
376
|
+
left_x = autocomplete_dialog.column - width
|
|
377
|
+
left_x = 0 if left_x < 0
|
|
378
|
+
left_width = width > autocomplete_dialog.column ? autocomplete_dialog.column : width
|
|
379
|
+
if right_width.positive? and left_width.positive?
|
|
380
|
+
if right_width >= left_width
|
|
381
|
+
width = right_width
|
|
382
|
+
x = right_x
|
|
383
|
+
else
|
|
384
|
+
width = left_width
|
|
385
|
+
x = left_x
|
|
386
|
+
end
|
|
387
|
+
elsif right_width.positive? and left_width <= 0
|
|
388
|
+
width = right_width
|
|
389
|
+
x = right_x
|
|
390
|
+
elsif right_width <= 0 and left_width.positive?
|
|
391
|
+
width = left_width
|
|
392
|
+
x = left_x
|
|
393
|
+
else # Both are negative width.
|
|
394
|
+
return nil
|
|
395
|
+
end
|
|
396
|
+
else
|
|
397
|
+
x = right_x
|
|
398
|
+
end
|
|
373
399
|
formatter = RDoc::Markup::ToAnsi.new
|
|
374
400
|
formatter.width = width
|
|
375
401
|
dialog.trap_key = alt_d
|
|
376
402
|
message = 'Press Alt+d to read the full document'
|
|
377
403
|
contents = [message] + doc.accept(formatter).split("\n")
|
|
378
404
|
|
|
379
|
-
x = cursor_pos_to_render.x + autocomplete_dialog.width
|
|
380
|
-
x = autocomplete_dialog.column - width if x + width >= screen_width
|
|
381
405
|
y = cursor_pos_to_render.y
|
|
382
406
|
DialogRenderInfo.new(pos: Reline::CursorPos.new(x, y), contents: contents, width: width, bg_color: '49')
|
|
383
407
|
}
|
data/lib/irb/lc/help-message
CHANGED
|
@@ -20,8 +20,15 @@ Usage: irb.rb [options] [programfile] [arguments]
|
|
|
20
20
|
-W[level=2] Same as `ruby -W`
|
|
21
21
|
--context-mode n Set n[0-4] to method to create Binding Object,
|
|
22
22
|
when new workspace was created
|
|
23
|
-
--
|
|
23
|
+
--extra-doc-dir Add an extra doc dir for the doc dialog
|
|
24
|
+
--echo Show result (default)
|
|
24
25
|
--noecho Don't show result
|
|
26
|
+
--echo-on-assignment
|
|
27
|
+
Show result on assignment
|
|
28
|
+
--noecho-on-assignment
|
|
29
|
+
Don't show result on assignment
|
|
30
|
+
--truncate-echo-on-assignment
|
|
31
|
+
Show truncated result on assignment (default)
|
|
25
32
|
--inspect Use `inspect' for output
|
|
26
33
|
--noinspect Don't use inspect for output
|
|
27
34
|
--multiline Use multiline editor module
|
data/lib/irb/ruby-lex.rb
CHANGED
|
@@ -87,8 +87,8 @@ class RubyLex
|
|
|
87
87
|
tokens.each do |t|
|
|
88
88
|
partial_tokens << t
|
|
89
89
|
unprocessed_tokens << t
|
|
90
|
-
if t
|
|
91
|
-
t_str = t
|
|
90
|
+
if t.tok.include?("\n")
|
|
91
|
+
t_str = t.tok
|
|
92
92
|
t_str.each_line("\n") do |s|
|
|
93
93
|
code << s << "\n"
|
|
94
94
|
ltype, indent, continue, code_block_open = check_state(code, partial_tokens, context: context)
|
|
@@ -97,9 +97,10 @@ class RubyLex
|
|
|
97
97
|
end
|
|
98
98
|
unprocessed_tokens = []
|
|
99
99
|
else
|
|
100
|
-
code << t
|
|
100
|
+
code << t.tok
|
|
101
101
|
end
|
|
102
102
|
end
|
|
103
|
+
|
|
103
104
|
unless unprocessed_tokens.empty?
|
|
104
105
|
ltype, indent, continue, code_block_open = check_state(code, unprocessed_tokens, context: context)
|
|
105
106
|
result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
|
|
@@ -107,6 +108,7 @@ class RubyLex
|
|
|
107
108
|
result
|
|
108
109
|
end
|
|
109
110
|
end
|
|
111
|
+
|
|
110
112
|
if p.respond_to?(:call)
|
|
111
113
|
@input = p
|
|
112
114
|
elsif block_given?
|
|
@@ -153,19 +155,19 @@ class RubyLex
|
|
|
153
155
|
pos_to_index = {}
|
|
154
156
|
lexer.scan.each do |t|
|
|
155
157
|
next if t.pos.first == 0
|
|
156
|
-
if pos_to_index.has_key?(t
|
|
157
|
-
index = pos_to_index[t
|
|
158
|
+
if pos_to_index.has_key?(t.pos)
|
|
159
|
+
index = pos_to_index[t.pos]
|
|
158
160
|
found_tk = tokens[index]
|
|
159
|
-
if ERROR_TOKENS.include?(found_tk
|
|
161
|
+
if ERROR_TOKENS.include?(found_tk.event) && !ERROR_TOKENS.include?(t.event)
|
|
160
162
|
tokens[index] = t
|
|
161
163
|
end
|
|
162
164
|
else
|
|
163
|
-
pos_to_index[t
|
|
165
|
+
pos_to_index[t.pos] = tokens.size
|
|
164
166
|
tokens << t
|
|
165
167
|
end
|
|
166
168
|
end
|
|
167
169
|
else
|
|
168
|
-
tokens = lexer.parse
|
|
170
|
+
tokens = lexer.parse.reject { |it| it.pos.first == 0 }
|
|
169
171
|
end
|
|
170
172
|
end
|
|
171
173
|
tokens
|
|
@@ -175,17 +177,17 @@ class RubyLex
|
|
|
175
177
|
|
|
176
178
|
def find_prev_spaces(line_index)
|
|
177
179
|
return 0 if @tokens.size == 0
|
|
178
|
-
md = @tokens[0]
|
|
180
|
+
md = @tokens[0].tok.match(/(\A +)/)
|
|
179
181
|
prev_spaces = md.nil? ? 0 : md[1].count(' ')
|
|
180
182
|
line_count = 0
|
|
181
183
|
@tokens.each_with_index do |t, i|
|
|
182
|
-
if t
|
|
183
|
-
line_count += t
|
|
184
|
+
if t.tok.include?("\n")
|
|
185
|
+
line_count += t.tok.count("\n")
|
|
184
186
|
if line_count >= line_index
|
|
185
187
|
return prev_spaces
|
|
186
188
|
end
|
|
187
189
|
if (@tokens.size - 1) > i
|
|
188
|
-
md = @tokens[i + 1]
|
|
190
|
+
md = @tokens[i + 1].tok.match(/(\A +)/)
|
|
189
191
|
prev_spaces = md.nil? ? 0 : md[1].count(' ')
|
|
190
192
|
end
|
|
191
193
|
end
|
|
@@ -207,7 +209,7 @@ class RubyLex
|
|
|
207
209
|
last_line = lines[line_index]&.byteslice(0, byte_pointer)
|
|
208
210
|
code += last_line if last_line
|
|
209
211
|
@tokens = self.class.ripper_lex_without_warning(code, context: context)
|
|
210
|
-
corresponding_token_depth = check_corresponding_token_depth
|
|
212
|
+
corresponding_token_depth = check_corresponding_token_depth(lines, line_index)
|
|
211
213
|
if corresponding_token_depth
|
|
212
214
|
corresponding_token_depth
|
|
213
215
|
else
|
|
@@ -295,18 +297,18 @@ class RubyLex
|
|
|
295
297
|
|
|
296
298
|
def process_continue(tokens = @tokens)
|
|
297
299
|
# last token is always newline
|
|
298
|
-
if tokens.size >= 2 and tokens[-2]
|
|
300
|
+
if tokens.size >= 2 and tokens[-2].event == :on_regexp_end
|
|
299
301
|
# end of regexp literal
|
|
300
302
|
return false
|
|
301
|
-
elsif tokens.size >= 2 and tokens[-2]
|
|
303
|
+
elsif tokens.size >= 2 and tokens[-2].event == :on_semicolon
|
|
302
304
|
return false
|
|
303
|
-
elsif tokens.size >= 2 and tokens[-2]
|
|
305
|
+
elsif tokens.size >= 2 and tokens[-2].event == :on_kw and ['begin', 'else', 'ensure'].include?(tokens[-2].tok)
|
|
304
306
|
return false
|
|
305
|
-
elsif !tokens.empty? and tokens.last
|
|
307
|
+
elsif !tokens.empty? and tokens.last.tok == "\\\n"
|
|
306
308
|
return true
|
|
307
|
-
elsif tokens.size >= 1 and tokens[-1]
|
|
309
|
+
elsif tokens.size >= 1 and tokens[-1].event == :on_heredoc_end # "EOH\n"
|
|
308
310
|
return false
|
|
309
|
-
elsif tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and tokens[-2]
|
|
311
|
+
elsif tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and tokens[-2].state.anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME) and tokens[-2].tok !~ /\A\.\.\.?\z/
|
|
310
312
|
# end of literal except for regexp
|
|
311
313
|
# endless range at end of line is not a continue
|
|
312
314
|
return true
|
|
@@ -316,7 +318,7 @@ class RubyLex
|
|
|
316
318
|
|
|
317
319
|
def check_code_block(code, tokens = @tokens)
|
|
318
320
|
return true if tokens.empty?
|
|
319
|
-
if tokens.last
|
|
321
|
+
if tokens.last.event == :on_heredoc_beg
|
|
320
322
|
return true
|
|
321
323
|
end
|
|
322
324
|
|
|
@@ -388,7 +390,7 @@ class RubyLex
|
|
|
388
390
|
end
|
|
389
391
|
|
|
390
392
|
if defined?(Ripper::EXPR_BEG)
|
|
391
|
-
last_lex_state = tokens.last
|
|
393
|
+
last_lex_state = tokens.last.state
|
|
392
394
|
if last_lex_state.allbits?(Ripper::EXPR_BEG)
|
|
393
395
|
return false
|
|
394
396
|
elsif last_lex_state.allbits?(Ripper::EXPR_DOT)
|
|
@@ -413,14 +415,14 @@ class RubyLex
|
|
|
413
415
|
tokens.each_with_index { |t, index|
|
|
414
416
|
# detecting one-liner method definition
|
|
415
417
|
if in_oneliner_def.nil?
|
|
416
|
-
if t
|
|
418
|
+
if t.state.allbits?(Ripper::EXPR_ENDFN)
|
|
417
419
|
in_oneliner_def = :ENDFN
|
|
418
420
|
end
|
|
419
421
|
else
|
|
420
|
-
if t
|
|
422
|
+
if t.state.allbits?(Ripper::EXPR_ENDFN)
|
|
421
423
|
# continuing
|
|
422
|
-
elsif t
|
|
423
|
-
if t
|
|
424
|
+
elsif t.state.allbits?(Ripper::EXPR_BEG)
|
|
425
|
+
if t.tok == '='
|
|
424
426
|
in_oneliner_def = :BODY
|
|
425
427
|
end
|
|
426
428
|
else
|
|
@@ -432,14 +434,14 @@ class RubyLex
|
|
|
432
434
|
end
|
|
433
435
|
end
|
|
434
436
|
|
|
435
|
-
case t
|
|
437
|
+
case t.event
|
|
436
438
|
when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
|
|
437
439
|
indent += 1
|
|
438
440
|
when :on_rbracket, :on_rbrace, :on_rparen
|
|
439
441
|
indent -= 1
|
|
440
442
|
when :on_kw
|
|
441
|
-
next if index > 0 and tokens[index - 1]
|
|
442
|
-
case t
|
|
443
|
+
next if index > 0 and tokens[index - 1].state.allbits?(Ripper::EXPR_FNAME)
|
|
444
|
+
case t.tok
|
|
443
445
|
when 'do'
|
|
444
446
|
syntax_of_do = take_corresponding_syntax_to_kw_do(tokens, index)
|
|
445
447
|
indent += 1 if syntax_of_do == :method_calling
|
|
@@ -447,7 +449,7 @@ class RubyLex
|
|
|
447
449
|
indent += 1
|
|
448
450
|
when 'if', 'unless', 'while', 'until'
|
|
449
451
|
# postfix if/unless/while/until must be Ripper::EXPR_LABEL
|
|
450
|
-
indent += 1 unless t
|
|
452
|
+
indent += 1 unless t.state.allbits?(Ripper::EXPR_LABEL)
|
|
451
453
|
when 'end'
|
|
452
454
|
indent -= 1
|
|
453
455
|
end
|
|
@@ -459,14 +461,14 @@ class RubyLex
|
|
|
459
461
|
|
|
460
462
|
def is_method_calling?(tokens, index)
|
|
461
463
|
tk = tokens[index]
|
|
462
|
-
if tk
|
|
464
|
+
if tk.state.anybits?(Ripper::EXPR_CMDARG) and tk.event == :on_ident
|
|
463
465
|
# The target method call to pass the block with "do".
|
|
464
466
|
return true
|
|
465
|
-
elsif tk
|
|
466
|
-
non_sp_index = tokens[0..(index - 1)].rindex{ |t| t
|
|
467
|
+
elsif tk.state.anybits?(Ripper::EXPR_ARG) and tk.event == :on_ident
|
|
468
|
+
non_sp_index = tokens[0..(index - 1)].rindex{ |t| t.event != :on_sp }
|
|
467
469
|
if non_sp_index
|
|
468
470
|
prev_tk = tokens[non_sp_index]
|
|
469
|
-
if prev_tk
|
|
471
|
+
if prev_tk.state.anybits?(Ripper::EXPR_DOT) and prev_tk.event == :on_period
|
|
470
472
|
# The target method call with receiver to pass the block with "do".
|
|
471
473
|
return true
|
|
472
474
|
end
|
|
@@ -477,21 +479,21 @@ class RubyLex
|
|
|
477
479
|
|
|
478
480
|
def take_corresponding_syntax_to_kw_do(tokens, index)
|
|
479
481
|
syntax_of_do = nil
|
|
480
|
-
# Finding a syntax
|
|
482
|
+
# Finding a syntax corresponding to "do".
|
|
481
483
|
index.downto(0) do |i|
|
|
482
484
|
tk = tokens[i]
|
|
483
485
|
# In "continue", the token isn't the corresponding syntax to "do".
|
|
484
|
-
non_sp_index = tokens[0..(i - 1)].rindex{ |t| t
|
|
486
|
+
non_sp_index = tokens[0..(i - 1)].rindex{ |t| t.event != :on_sp }
|
|
485
487
|
first_in_fomula = false
|
|
486
488
|
if non_sp_index.nil?
|
|
487
489
|
first_in_fomula = true
|
|
488
|
-
elsif [:on_ignored_nl, :on_nl, :on_comment].include?(tokens[non_sp_index]
|
|
490
|
+
elsif [:on_ignored_nl, :on_nl, :on_comment].include?(tokens[non_sp_index].event)
|
|
489
491
|
first_in_fomula = true
|
|
490
492
|
end
|
|
491
493
|
if is_method_calling?(tokens, i)
|
|
492
494
|
syntax_of_do = :method_calling
|
|
493
495
|
break if first_in_fomula
|
|
494
|
-
elsif tk
|
|
496
|
+
elsif tk.event == :on_kw && %w{while until for}.include?(tk.tok)
|
|
495
497
|
# A loop syntax in front of "do" found.
|
|
496
498
|
#
|
|
497
499
|
# while cond do # also "until" or "for"
|
|
@@ -508,18 +510,18 @@ class RubyLex
|
|
|
508
510
|
|
|
509
511
|
def is_the_in_correspond_to_a_for(tokens, index)
|
|
510
512
|
syntax_of_in = nil
|
|
511
|
-
# Finding a syntax
|
|
513
|
+
# Finding a syntax corresponding to "do".
|
|
512
514
|
index.downto(0) do |i|
|
|
513
515
|
tk = tokens[i]
|
|
514
516
|
# In "continue", the token isn't the corresponding syntax to "do".
|
|
515
|
-
non_sp_index = tokens[0..(i - 1)].rindex{ |t| t
|
|
517
|
+
non_sp_index = tokens[0..(i - 1)].rindex{ |t| t.event != :on_sp }
|
|
516
518
|
first_in_fomula = false
|
|
517
519
|
if non_sp_index.nil?
|
|
518
520
|
first_in_fomula = true
|
|
519
|
-
elsif [:on_ignored_nl, :on_nl, :on_comment].include?(tokens[non_sp_index]
|
|
521
|
+
elsif [:on_ignored_nl, :on_nl, :on_comment].include?(tokens[non_sp_index].event)
|
|
520
522
|
first_in_fomula = true
|
|
521
523
|
end
|
|
522
|
-
if tk
|
|
524
|
+
if tk.event == :on_kw && tk.tok == 'for'
|
|
523
525
|
# A loop syntax in front of "do" found.
|
|
524
526
|
#
|
|
525
527
|
# while cond do # also "until" or "for"
|
|
@@ -541,14 +543,14 @@ class RubyLex
|
|
|
541
543
|
@tokens.each_with_index do |t, index|
|
|
542
544
|
# detecting one-liner method definition
|
|
543
545
|
if in_oneliner_def.nil?
|
|
544
|
-
if t
|
|
546
|
+
if t.state.allbits?(Ripper::EXPR_ENDFN)
|
|
545
547
|
in_oneliner_def = :ENDFN
|
|
546
548
|
end
|
|
547
549
|
else
|
|
548
|
-
if t
|
|
550
|
+
if t.state.allbits?(Ripper::EXPR_ENDFN)
|
|
549
551
|
# continuing
|
|
550
|
-
elsif t
|
|
551
|
-
if t
|
|
552
|
+
elsif t.state.allbits?(Ripper::EXPR_BEG)
|
|
553
|
+
if t.tok == '='
|
|
552
554
|
in_oneliner_def = :BODY
|
|
553
555
|
end
|
|
554
556
|
else
|
|
@@ -560,7 +562,7 @@ class RubyLex
|
|
|
560
562
|
end
|
|
561
563
|
end
|
|
562
564
|
|
|
563
|
-
case t
|
|
565
|
+
case t.event
|
|
564
566
|
when :on_ignored_nl, :on_nl, :on_comment
|
|
565
567
|
if index != (@tokens.size - 1) and in_oneliner_def != :BODY
|
|
566
568
|
depth_difference = 0
|
|
@@ -570,15 +572,16 @@ class RubyLex
|
|
|
570
572
|
when :on_sp
|
|
571
573
|
next
|
|
572
574
|
end
|
|
573
|
-
|
|
575
|
+
|
|
576
|
+
case t.event
|
|
574
577
|
when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
|
|
575
578
|
depth_difference += 1
|
|
576
579
|
open_brace_on_line += 1
|
|
577
580
|
when :on_rbracket, :on_rbrace, :on_rparen
|
|
578
581
|
depth_difference -= 1 if open_brace_on_line > 0
|
|
579
582
|
when :on_kw
|
|
580
|
-
next if index > 0 and @tokens[index - 1]
|
|
581
|
-
case t
|
|
583
|
+
next if index > 0 and @tokens[index - 1].state.allbits?(Ripper::EXPR_FNAME)
|
|
584
|
+
case t.tok
|
|
582
585
|
when 'do'
|
|
583
586
|
syntax_of_do = take_corresponding_syntax_to_kw_do(@tokens, index)
|
|
584
587
|
depth_difference += 1 if syntax_of_do == :method_calling
|
|
@@ -586,7 +589,7 @@ class RubyLex
|
|
|
586
589
|
depth_difference += 1
|
|
587
590
|
when 'if', 'unless', 'while', 'until', 'rescue'
|
|
588
591
|
# postfix if/unless/while/until/rescue must be Ripper::EXPR_LABEL
|
|
589
|
-
unless t
|
|
592
|
+
unless t.state.allbits?(Ripper::EXPR_LABEL)
|
|
590
593
|
depth_difference += 1
|
|
591
594
|
end
|
|
592
595
|
when 'else', 'elsif', 'ensure', 'when'
|
|
@@ -603,7 +606,7 @@ class RubyLex
|
|
|
603
606
|
depth_difference
|
|
604
607
|
end
|
|
605
608
|
|
|
606
|
-
def check_corresponding_token_depth
|
|
609
|
+
def check_corresponding_token_depth(lines, line_index)
|
|
607
610
|
corresponding_token_depth = nil
|
|
608
611
|
is_first_spaces_of_line = true
|
|
609
612
|
is_first_printable_of_line = true
|
|
@@ -611,17 +614,22 @@ class RubyLex
|
|
|
611
614
|
spaces_at_line_head = 0
|
|
612
615
|
open_brace_on_line = 0
|
|
613
616
|
in_oneliner_def = nil
|
|
617
|
+
|
|
618
|
+
if heredoc_scope?
|
|
619
|
+
return lines[line_index][/^ */].length
|
|
620
|
+
end
|
|
621
|
+
|
|
614
622
|
@tokens.each_with_index do |t, index|
|
|
615
623
|
# detecting one-liner method definition
|
|
616
624
|
if in_oneliner_def.nil?
|
|
617
|
-
if t
|
|
625
|
+
if t.state.allbits?(Ripper::EXPR_ENDFN)
|
|
618
626
|
in_oneliner_def = :ENDFN
|
|
619
627
|
end
|
|
620
628
|
else
|
|
621
|
-
if t
|
|
629
|
+
if t.state.allbits?(Ripper::EXPR_ENDFN)
|
|
622
630
|
# continuing
|
|
623
|
-
elsif t
|
|
624
|
-
if t
|
|
631
|
+
elsif t.state.allbits?(Ripper::EXPR_BEG)
|
|
632
|
+
if t.tok == '='
|
|
625
633
|
in_oneliner_def = :BODY
|
|
626
634
|
end
|
|
627
635
|
else
|
|
@@ -638,7 +646,7 @@ class RubyLex
|
|
|
638
646
|
end
|
|
639
647
|
end
|
|
640
648
|
|
|
641
|
-
case t
|
|
649
|
+
case t.event
|
|
642
650
|
when :on_ignored_nl, :on_nl, :on_comment
|
|
643
651
|
if in_oneliner_def != :BODY
|
|
644
652
|
corresponding_token_depth = nil
|
|
@@ -649,11 +657,12 @@ class RubyLex
|
|
|
649
657
|
end
|
|
650
658
|
next
|
|
651
659
|
when :on_sp
|
|
652
|
-
spaces_at_line_head = t
|
|
660
|
+
spaces_at_line_head = t.tok.count(' ') if is_first_spaces_of_line
|
|
653
661
|
is_first_spaces_of_line = false
|
|
654
662
|
next
|
|
655
663
|
end
|
|
656
|
-
|
|
664
|
+
|
|
665
|
+
case t.event
|
|
657
666
|
when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
|
|
658
667
|
spaces_of_nest.push(spaces_at_line_head + open_brace_on_line * 2)
|
|
659
668
|
open_brace_on_line += 1
|
|
@@ -666,8 +675,8 @@ class RubyLex
|
|
|
666
675
|
end
|
|
667
676
|
open_brace_on_line -= 1
|
|
668
677
|
when :on_kw
|
|
669
|
-
next if index > 0 and @tokens[index - 1]
|
|
670
|
-
case t
|
|
678
|
+
next if index > 0 and @tokens[index - 1].state.allbits?(Ripper::EXPR_FNAME)
|
|
679
|
+
case t.tok
|
|
671
680
|
when 'do'
|
|
672
681
|
syntax_of_do = take_corresponding_syntax_to_kw_do(@tokens, index)
|
|
673
682
|
if syntax_of_do == :method_calling
|
|
@@ -676,16 +685,20 @@ class RubyLex
|
|
|
676
685
|
when 'def', 'case', 'for', 'begin', 'class', 'module'
|
|
677
686
|
spaces_of_nest.push(spaces_at_line_head)
|
|
678
687
|
when 'rescue'
|
|
679
|
-
unless t
|
|
688
|
+
unless t.state.allbits?(Ripper::EXPR_LABEL)
|
|
680
689
|
corresponding_token_depth = spaces_of_nest.last
|
|
681
690
|
end
|
|
682
691
|
when 'if', 'unless', 'while', 'until'
|
|
683
692
|
# postfix if/unless/while/until must be Ripper::EXPR_LABEL
|
|
684
|
-
unless t
|
|
693
|
+
unless t.state.allbits?(Ripper::EXPR_LABEL)
|
|
685
694
|
spaces_of_nest.push(spaces_at_line_head)
|
|
686
695
|
end
|
|
687
|
-
when 'else', 'elsif', 'ensure', 'when'
|
|
696
|
+
when 'else', 'elsif', 'ensure', 'when'
|
|
688
697
|
corresponding_token_depth = spaces_of_nest.last
|
|
698
|
+
when 'in'
|
|
699
|
+
if in_keyword_case_scope?
|
|
700
|
+
corresponding_token_depth = spaces_of_nest.last
|
|
701
|
+
end
|
|
689
702
|
when 'end'
|
|
690
703
|
if is_first_printable_of_line
|
|
691
704
|
corresponding_token_depth = spaces_of_nest.pop
|
|
@@ -707,7 +720,10 @@ class RubyLex
|
|
|
707
720
|
end_type = []
|
|
708
721
|
while i < tokens.size
|
|
709
722
|
t = tokens[i]
|
|
710
|
-
case t
|
|
723
|
+
case t.event
|
|
724
|
+
when *end_type.last
|
|
725
|
+
start_token.pop
|
|
726
|
+
end_type.pop
|
|
711
727
|
when :on_tstring_beg
|
|
712
728
|
start_token << t
|
|
713
729
|
end_type << [:on_tstring_end, :on_label_end]
|
|
@@ -715,10 +731,14 @@ class RubyLex
|
|
|
715
731
|
start_token << t
|
|
716
732
|
end_type << :on_regexp_end
|
|
717
733
|
when :on_symbeg
|
|
718
|
-
acceptable_single_tokens = %i{on_ident on_const on_op on_cvar on_ivar on_gvar on_kw on_int}
|
|
719
|
-
if (i + 1) < tokens.size
|
|
720
|
-
|
|
721
|
-
|
|
734
|
+
acceptable_single_tokens = %i{on_ident on_const on_op on_cvar on_ivar on_gvar on_kw on_int on_backtick}
|
|
735
|
+
if (i + 1) < tokens.size
|
|
736
|
+
if acceptable_single_tokens.all?{ |st| tokens[i + 1].event != st }
|
|
737
|
+
start_token << t
|
|
738
|
+
end_type << :on_tstring_end
|
|
739
|
+
else
|
|
740
|
+
i += 1
|
|
741
|
+
end
|
|
722
742
|
end
|
|
723
743
|
when :on_backtick
|
|
724
744
|
start_token << t
|
|
@@ -729,20 +749,19 @@ class RubyLex
|
|
|
729
749
|
when :on_heredoc_beg
|
|
730
750
|
start_token << t
|
|
731
751
|
end_type << :on_heredoc_end
|
|
732
|
-
when *end_type.last
|
|
733
|
-
start_token.pop
|
|
734
|
-
end_type.pop
|
|
735
752
|
end
|
|
736
753
|
i += 1
|
|
737
754
|
end
|
|
738
|
-
start_token.last.nil? ?
|
|
755
|
+
start_token.last.nil? ? nil : start_token.last
|
|
739
756
|
end
|
|
740
757
|
|
|
741
758
|
def process_literal_type(tokens = @tokens)
|
|
742
759
|
start_token = check_string_literal(tokens)
|
|
743
|
-
|
|
760
|
+
return nil if start_token == ""
|
|
761
|
+
|
|
762
|
+
case start_token&.event
|
|
744
763
|
when :on_tstring_beg
|
|
745
|
-
case start_token
|
|
764
|
+
case start_token&.tok
|
|
746
765
|
when ?" then ?"
|
|
747
766
|
when /^%.$/ then ?"
|
|
748
767
|
when /^%Q.$/ then ?"
|
|
@@ -757,7 +776,7 @@ class RubyLex
|
|
|
757
776
|
when :on_qsymbols_beg then ?]
|
|
758
777
|
when :on_symbols_beg then ?]
|
|
759
778
|
when :on_heredoc_beg
|
|
760
|
-
start_token
|
|
779
|
+
start_token&.tok =~ /<<[-~]?(['"`])[_a-zA-Z0-9]+\1/
|
|
761
780
|
case $1
|
|
762
781
|
when ?" then ?"
|
|
763
782
|
when ?' then ?'
|
|
@@ -785,6 +804,7 @@ class RubyLex
|
|
|
785
804
|
false
|
|
786
805
|
end
|
|
787
806
|
end
|
|
807
|
+
|
|
788
808
|
if index
|
|
789
809
|
first_token = nil
|
|
790
810
|
last_line_tokens = tokens[(index + 1)..(tokens.size - 1)]
|
|
@@ -794,6 +814,7 @@ class RubyLex
|
|
|
794
814
|
break
|
|
795
815
|
end
|
|
796
816
|
end
|
|
817
|
+
|
|
797
818
|
if first_token.nil?
|
|
798
819
|
return false
|
|
799
820
|
elsif first_token && first_token.state == Ripper::EXPR_DOT
|
|
@@ -813,5 +834,28 @@ class RubyLex
|
|
|
813
834
|
end
|
|
814
835
|
false
|
|
815
836
|
end
|
|
837
|
+
|
|
838
|
+
private
|
|
839
|
+
|
|
840
|
+
def heredoc_scope?
|
|
841
|
+
heredoc_tokens = @tokens.select { |t| [:on_heredoc_beg, :on_heredoc_end].include?(t.event) }
|
|
842
|
+
heredoc_tokens[-1]&.event == :on_heredoc_beg
|
|
843
|
+
end
|
|
844
|
+
|
|
845
|
+
def in_keyword_case_scope?
|
|
846
|
+
kw_tokens = @tokens.select { |t| t.event == :on_kw && ['case', 'for', 'end'].include?(t.tok) }
|
|
847
|
+
counter = 0
|
|
848
|
+
kw_tokens.reverse.each do |t|
|
|
849
|
+
if t.tok == 'case'
|
|
850
|
+
return true if counter.zero?
|
|
851
|
+
counter += 1
|
|
852
|
+
elsif t.tok == 'for'
|
|
853
|
+
counter += 1
|
|
854
|
+
elsif t.tok == 'end'
|
|
855
|
+
counter -= 1
|
|
856
|
+
end
|
|
857
|
+
end
|
|
858
|
+
false
|
|
859
|
+
end
|
|
816
860
|
end
|
|
817
861
|
# :startdoc:
|
data/lib/irb/version.rb
CHANGED
data/lib/irb/workspace.rb
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
require "delegate"
|
|
14
14
|
|
|
15
|
+
IRB::TOPLEVEL_BINDING = binding
|
|
15
16
|
module IRB # :nodoc:
|
|
16
17
|
class WorkSpace
|
|
17
18
|
# Creates a new workspace.
|
|
@@ -57,6 +58,8 @@ EOF
|
|
|
57
58
|
__FILE__,
|
|
58
59
|
__LINE__ - 3)
|
|
59
60
|
when 4 # binding is a copy of TOPLEVEL_BINDING (default)
|
|
61
|
+
# Note that this will typically be IRB::TOPLEVEL_BINDING
|
|
62
|
+
# This is to avoid RubyGems' local variables (see issue #17623)
|
|
60
63
|
@binding = TOPLEVEL_BINDING.dup
|
|
61
64
|
end
|
|
62
65
|
end
|
data/lib/irb.rb
CHANGED
|
@@ -62,8 +62,15 @@ require_relative "irb/easter-egg"
|
|
|
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
64
|
# when new workspace was created
|
|
65
|
-
# --
|
|
65
|
+
# --extra-doc-dir Add an extra doc dir for the doc dialog
|
|
66
|
+
# --echo Show result (default)
|
|
66
67
|
# --noecho Don't show result
|
|
68
|
+
# --echo-on-assignment
|
|
69
|
+
# Show result on assignment
|
|
70
|
+
# --noecho-on-assignment
|
|
71
|
+
# Don't show result on assignment
|
|
72
|
+
# --truncate-echo-on-assignment
|
|
73
|
+
# Show truncated result on assignment (default)
|
|
67
74
|
# --inspect Use `inspect' for output
|
|
68
75
|
# --noinspect Don't use inspect for output
|
|
69
76
|
# --multiline Use multiline editor module
|
|
@@ -607,7 +614,7 @@ module IRB
|
|
|
607
614
|
ret = conv.primitive_convert(str, dst)
|
|
608
615
|
case ret
|
|
609
616
|
when :invalid_byte_sequence
|
|
610
|
-
conv.insert_output(
|
|
617
|
+
conv.insert_output(conv.primitive_errinfo[3].dump[1..-2])
|
|
611
618
|
redo
|
|
612
619
|
when :undefined_conversion
|
|
613
620
|
c = conv.primitive_errinfo[3].dup.force_encoding(conv.primitive_errinfo[1])
|
|
@@ -669,6 +676,8 @@ module IRB
|
|
|
669
676
|
lines = lines.reverse if order == :bottom
|
|
670
677
|
lines.map{ |l| l + "\n" }.join
|
|
671
678
|
}
|
|
679
|
+
# The "<top (required)>" in "(irb)" may be the top level of IRB so imitate the main object.
|
|
680
|
+
message = message.gsub(/\(irb\):(?<num>\d+):in `<(?<frame>top \(required\))>'/) { "(irb):#{$~[:num]}:in `<main>'" }
|
|
672
681
|
puts message
|
|
673
682
|
end
|
|
674
683
|
print "Maybe IRB bug!\n" if irb_bug
|
|
@@ -815,17 +824,20 @@ module IRB
|
|
|
815
824
|
diff_size = output_width - Reline::Unicode.calculate_width(first_line, true)
|
|
816
825
|
if diff_size.positive? and output_width > winwidth
|
|
817
826
|
lines, _ = Reline::Unicode.split_by_width(first_line, winwidth - diff_size - 3)
|
|
818
|
-
str = "%s
|
|
827
|
+
str = "%s..." % lines.first
|
|
828
|
+
str += "\e[0m" if @context.use_colorize
|
|
819
829
|
multiline_p = false
|
|
820
830
|
else
|
|
821
831
|
str = str.gsub(/(\A.*?\n).*/m, "\\1...")
|
|
832
|
+
str += "\e[0m" if @context.use_colorize
|
|
822
833
|
end
|
|
823
834
|
else
|
|
824
835
|
output_width = Reline::Unicode.calculate_width(@context.return_format % str, true)
|
|
825
836
|
diff_size = output_width - Reline::Unicode.calculate_width(str, true)
|
|
826
837
|
if diff_size.positive? and output_width > winwidth
|
|
827
838
|
lines, _ = Reline::Unicode.split_by_width(str, winwidth - diff_size - 3)
|
|
828
|
-
str = "%s
|
|
839
|
+
str = "%s..." % lines.first
|
|
840
|
+
str += "\e[0m" if @context.use_colorize
|
|
829
841
|
end
|
|
830
842
|
end
|
|
831
843
|
end
|
|
@@ -859,7 +871,7 @@ module IRB
|
|
|
859
871
|
|
|
860
872
|
# If the expression is invalid, Ripper.sexp should return nil which will
|
|
861
873
|
# result in false being returned. Any valid expression should return an
|
|
862
|
-
# s-expression where the second
|
|
874
|
+
# s-expression where the second element of the top level array is an
|
|
863
875
|
# array of parsed expressions. The first element of each expression is the
|
|
864
876
|
# expression's type.
|
|
865
877
|
verbose, $VERBOSE = $VERBOSE, nil
|
data/man/irb.1
CHANGED
|
@@ -105,13 +105,27 @@ Uses singleline editor module.
|
|
|
105
105
|
Doesn't use singleline editor module.
|
|
106
106
|
.Pp
|
|
107
107
|
.Pp
|
|
108
|
+
.It Fl -extra-doc-dir
|
|
109
|
+
Add an extra doc dir for the doc dialog.
|
|
110
|
+
.Pp
|
|
111
|
+
.Pp
|
|
108
112
|
.It Fl -echo
|
|
109
|
-
Show result(default).
|
|
113
|
+
Show result (default).
|
|
110
114
|
.Pp
|
|
111
115
|
.It Fl -noecho
|
|
112
116
|
Don't show result.
|
|
113
117
|
.Pp
|
|
114
118
|
.Pp
|
|
119
|
+
.It Fl -echo-on-assignment
|
|
120
|
+
Show result on assignment.
|
|
121
|
+
.Pp
|
|
122
|
+
.It Fl -noecho-on-assignment
|
|
123
|
+
Don't show result on assignment.
|
|
124
|
+
.Pp
|
|
125
|
+
.It Fl -truncate-echo-on-assignment
|
|
126
|
+
Show truncated result on assignment (default).
|
|
127
|
+
.Pp
|
|
128
|
+
.Pp
|
|
115
129
|
.It Fl -colorize
|
|
116
130
|
Use colorization.
|
|
117
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.
|
|
4
|
+
version: 1.4.0
|
|
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-12-24 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.3.0
|
|
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.3.0
|
|
27
27
|
description: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).
|
|
28
28
|
email:
|
|
29
29
|
- keiju@ruby-lang.org
|
|
@@ -108,9 +108,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
108
108
|
version: '2.5'
|
|
109
109
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
110
|
requirements:
|
|
111
|
-
- - "
|
|
111
|
+
- - ">="
|
|
112
112
|
- !ruby/object:Gem::Version
|
|
113
|
-
version:
|
|
113
|
+
version: '0'
|
|
114
114
|
requirements: []
|
|
115
115
|
rubygems_version: 3.2.22
|
|
116
116
|
signing_key:
|