irb 1.3.0 → 1.3.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +7 -0
- data/irb.gemspec +1 -44
- data/lib/irb.rb +76 -46
- data/lib/irb/cmd/info.rb +25 -0
- data/lib/irb/cmd/ls.rb +83 -0
- data/lib/irb/cmd/measure.rb +10 -4
- data/lib/irb/cmd/nop.rb +10 -4
- data/lib/irb/cmd/show_source.rb +86 -0
- data/lib/irb/cmd/whereami.rb +20 -0
- data/lib/irb/color.rb +20 -4
- data/lib/irb/color_printer.rb +47 -0
- data/lib/irb/completion.rb +84 -14
- data/lib/irb/ext/loader.rb +46 -19
- data/lib/irb/ext/save-history.rb +15 -5
- data/lib/irb/extend-command.rb +21 -4
- data/lib/irb/init.rb +11 -1
- data/lib/irb/input-method.rb +19 -2
- data/lib/irb/inspector.rb +12 -14
- data/lib/irb/lc/help-message +6 -6
- data/lib/irb/ruby-lex.rb +232 -43
- data/lib/irb/version.rb +2 -2
- data/lib/irb/workspace.rb +2 -1
- metadata +7 -2
data/lib/irb/extend-command.rb
CHANGED
@@ -126,7 +126,23 @@ module IRB # :nodoc:
|
|
126
126
|
],
|
127
127
|
|
128
128
|
[
|
129
|
-
:
|
129
|
+
:irb_ls, :Ls, "irb/cmd/ls",
|
130
|
+
[:ls, NO_OVERRIDE],
|
131
|
+
],
|
132
|
+
|
133
|
+
[
|
134
|
+
:irb_measure, :Measure, "irb/cmd/measure",
|
135
|
+
[:measure, NO_OVERRIDE],
|
136
|
+
],
|
137
|
+
|
138
|
+
[
|
139
|
+
:irb_show_source, :ShowSource, "irb/cmd/show_source",
|
140
|
+
[:show_source, NO_OVERRIDE],
|
141
|
+
],
|
142
|
+
|
143
|
+
[
|
144
|
+
:irb_whereami, :Whereami, "irb/cmd/whereami",
|
145
|
+
[:whereami, NO_OVERRIDE],
|
130
146
|
],
|
131
147
|
|
132
148
|
]
|
@@ -168,12 +184,13 @@ module IRB # :nodoc:
|
|
168
184
|
end
|
169
185
|
|
170
186
|
if load_file
|
187
|
+
kwargs = ", **kwargs" if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
|
171
188
|
line = __LINE__; eval %[
|
172
|
-
def #{cmd_name}(*opts, &b)
|
189
|
+
def #{cmd_name}(*opts#{kwargs}, &b)
|
173
190
|
require "#{load_file}"
|
174
191
|
arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity
|
175
192
|
args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s }
|
176
|
-
args << "*opts" if arity < 0
|
193
|
+
args << "*opts#{kwargs}" if arity < 0
|
177
194
|
args << "&block"
|
178
195
|
args = args.join(", ")
|
179
196
|
line = __LINE__; eval %[
|
@@ -184,7 +201,7 @@ module IRB # :nodoc:
|
|
184
201
|
end
|
185
202
|
end
|
186
203
|
], nil, __FILE__, line
|
187
|
-
__send__ :#{cmd_name}_, *opts, &b
|
204
|
+
__send__ :#{cmd_name}_, *opts#{kwargs}, &b
|
188
205
|
end
|
189
206
|
], nil, __FILE__, line
|
190
207
|
else
|
data/lib/irb/init.rb
CHANGED
@@ -146,7 +146,7 @@ module IRB # :nodoc:
|
|
146
146
|
@CONF[:AT_EXIT] = []
|
147
147
|
end
|
148
148
|
|
149
|
-
def IRB.set_measure_callback(type = nil, arg = nil)
|
149
|
+
def IRB.set_measure_callback(type = nil, arg = nil, &block)
|
150
150
|
added = nil
|
151
151
|
if type
|
152
152
|
type_sym = type.upcase.to_sym
|
@@ -155,6 +155,16 @@ module IRB # :nodoc:
|
|
155
155
|
end
|
156
156
|
elsif IRB.conf[:MEASURE_PROC][:CUSTOM]
|
157
157
|
added = [:CUSTOM, IRB.conf[:MEASURE_PROC][:CUSTOM], arg]
|
158
|
+
elsif block_given?
|
159
|
+
added = [:BLOCK, block, arg]
|
160
|
+
found = IRB.conf[:MEASURE_CALLBACKS].find{ |m| m[0] == added[0] && m[2] == added[2] }
|
161
|
+
if found
|
162
|
+
found[1] = block
|
163
|
+
return added
|
164
|
+
else
|
165
|
+
IRB.conf[:MEASURE_CALLBACKS] << added
|
166
|
+
return added
|
167
|
+
end
|
158
168
|
else
|
159
169
|
added = [:TIME, IRB.conf[:MEASURE_PROC][:TIME], arg]
|
160
170
|
end
|
data/lib/irb/input-method.rb
CHANGED
@@ -124,10 +124,22 @@ module IRB
|
|
124
124
|
|
125
125
|
# Use a File for IO with irb, see InputMethod
|
126
126
|
class FileInputMethod < InputMethod
|
127
|
+
class << self
|
128
|
+
def open(file, &block)
|
129
|
+
begin
|
130
|
+
io = new(file)
|
131
|
+
block.call(io)
|
132
|
+
ensure
|
133
|
+
io&.close
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
127
138
|
# Creates a new input method object
|
128
139
|
def initialize(file)
|
129
140
|
super
|
130
141
|
@io = IRB::MagicFile.open(file)
|
142
|
+
@external_encoding = @io.external_encoding
|
131
143
|
end
|
132
144
|
# The file name of this input method, usually given during initialization.
|
133
145
|
attr_reader :file_name
|
@@ -137,7 +149,7 @@ module IRB
|
|
137
149
|
#
|
138
150
|
# See IO#eof? for more information.
|
139
151
|
def eof?
|
140
|
-
@io.eof?
|
152
|
+
@io.closed? || @io.eof?
|
141
153
|
end
|
142
154
|
|
143
155
|
# Reads the next line from this input method.
|
@@ -150,13 +162,17 @@ module IRB
|
|
150
162
|
|
151
163
|
# The external encoding for standard input.
|
152
164
|
def encoding
|
153
|
-
@
|
165
|
+
@external_encoding
|
154
166
|
end
|
155
167
|
|
156
168
|
# For debug message
|
157
169
|
def inspect
|
158
170
|
'FileInputMethod'
|
159
171
|
end
|
172
|
+
|
173
|
+
def close
|
174
|
+
@io.close
|
175
|
+
end
|
160
176
|
end
|
161
177
|
|
162
178
|
begin
|
@@ -264,6 +280,7 @@ module IRB
|
|
264
280
|
Reline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
|
265
281
|
end
|
266
282
|
Reline.completion_append_character = nil
|
283
|
+
Reline.completer_quote_characters = ''
|
267
284
|
Reline.completion_proc = IRB::InputCompletor::CompletionProc
|
268
285
|
Reline.output_modifier_proc =
|
269
286
|
if IRB.conf[:USE_COLORIZE]
|
data/lib/irb/inspector.rb
CHANGED
@@ -100,29 +100,27 @@ module IRB # :nodoc:
|
|
100
100
|
# Proc to call when the input is evaluated and output in irb.
|
101
101
|
def inspect_value(v)
|
102
102
|
@inspect.call(v)
|
103
|
+
rescue
|
104
|
+
puts "(Object doesn't support #inspect)"
|
105
|
+
''
|
103
106
|
end
|
104
107
|
end
|
105
108
|
|
106
109
|
Inspector.def_inspector([false, :to_s, :raw]){|v| v.to_s}
|
107
|
-
Inspector.def_inspector([
|
108
|
-
|
109
|
-
result = v.inspect
|
110
|
-
if IRB.conf[:MAIN_CONTEXT]&.use_colorize? && Color.inspect_colorable?(v)
|
111
|
-
result = Color.colorize_code(result)
|
112
|
-
end
|
113
|
-
result
|
114
|
-
rescue NoMethodError
|
115
|
-
puts "(Object doesn't support #inspect)"
|
116
|
-
''
|
117
|
-
end
|
118
|
-
}
|
119
|
-
Inspector.def_inspector([:pp, :pretty_inspect], proc{require "pp"}){|v|
|
120
|
-
result = v.pretty_inspect.chomp
|
110
|
+
Inspector.def_inspector([:p, :inspect]){|v|
|
111
|
+
result = v.inspect
|
121
112
|
if IRB.conf[:MAIN_CONTEXT]&.use_colorize? && Color.inspect_colorable?(v)
|
122
113
|
result = Color.colorize_code(result)
|
123
114
|
end
|
124
115
|
result
|
125
116
|
}
|
117
|
+
Inspector.def_inspector([true, :pp, :pretty_inspect], proc{require "irb/color_printer"}){|v|
|
118
|
+
if IRB.conf[:MAIN_CONTEXT]&.use_colorize?
|
119
|
+
IRB::ColorPrinter.pp(v, '').chomp
|
120
|
+
else
|
121
|
+
v.pretty_inspect.chomp
|
122
|
+
end
|
123
|
+
}
|
126
124
|
Inspector.def_inspector([:yaml, :YAML], proc{require "yaml"}){|v|
|
127
125
|
begin
|
128
126
|
YAML.dump(v)
|
data/lib/irb/lc/help-message
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
#
|
12
12
|
Usage: irb.rb [options] [programfile] [arguments]
|
13
|
-
-f
|
13
|
+
-f Suppress read of ~/.irbrc
|
14
14
|
-d Set $DEBUG to true (same as `ruby -d')
|
15
15
|
-r load-module Same as `ruby -r'
|
16
16
|
-I path Specify $LOAD_PATH directory
|
@@ -18,7 +18,7 @@ Usage: irb.rb [options] [programfile] [arguments]
|
|
18
18
|
-E enc Same as `ruby -E`
|
19
19
|
-w Same as `ruby -w`
|
20
20
|
-W[level=2] Same as `ruby -W`
|
21
|
-
--context-mode n Set n[0-
|
21
|
+
--context-mode n Set n[0-4] to method to create Binding Object,
|
22
22
|
when new workspace was created
|
23
23
|
--echo Show result(default)
|
24
24
|
--noecho Don't show result
|
@@ -31,8 +31,8 @@ Usage: irb.rb [options] [programfile] [arguments]
|
|
31
31
|
--colorize Use colorization
|
32
32
|
--nocolorize Don't use colorization
|
33
33
|
--prompt prompt-mode/--prompt-mode prompt-mode
|
34
|
-
|
35
|
-
|
34
|
+
Switch prompt mode. Pre-defined prompt modes are
|
35
|
+
`default', `simple', `xmp' and `inf-ruby'
|
36
36
|
--inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
|
37
37
|
Suppresses --multiline and --singleline.
|
38
38
|
--sample-book-mode/--simple-prompt
|
@@ -41,8 +41,8 @@ Usage: irb.rb [options] [programfile] [arguments]
|
|
41
41
|
--single-irb Share self with sub-irb.
|
42
42
|
--tracer Display trace for each execution of commands.
|
43
43
|
--back-trace-limit n
|
44
|
-
|
45
|
-
|
44
|
+
Display backtrace top n and tail n. The default
|
45
|
+
value is 16.
|
46
46
|
--verbose Show details
|
47
47
|
--noverbose Don't show details
|
48
48
|
-v, --version Print the version of irb
|
data/lib/irb/ruby-lex.rb
CHANGED
@@ -47,12 +47,26 @@ class RubyLex
|
|
47
47
|
@io = io
|
48
48
|
if @io.respond_to?(:check_termination)
|
49
49
|
@io.check_termination do |code|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
if Reline::IOGate.in_pasting?
|
51
|
+
lex = RubyLex.new
|
52
|
+
rest = lex.check_termination_in_prev_line(code)
|
53
|
+
if rest
|
54
|
+
Reline.delete_text
|
55
|
+
rest.bytes.reverse_each do |c|
|
56
|
+
Reline.ungetc(c)
|
57
|
+
end
|
58
|
+
true
|
59
|
+
else
|
60
|
+
false
|
61
|
+
end
|
54
62
|
else
|
55
|
-
|
63
|
+
code.gsub!(/\s*\z/, '').concat("\n")
|
64
|
+
ltype, indent, continue, code_block_open = check_state(code)
|
65
|
+
if ltype or indent > 0 or continue or code_block_open
|
66
|
+
false
|
67
|
+
else
|
68
|
+
true
|
69
|
+
end
|
56
70
|
end
|
57
71
|
end
|
58
72
|
end
|
@@ -60,7 +74,7 @@ class RubyLex
|
|
60
74
|
@io.dynamic_prompt do |lines|
|
61
75
|
lines << '' if lines.empty?
|
62
76
|
result = []
|
63
|
-
tokens = ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join)
|
77
|
+
tokens = self.class.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join)
|
64
78
|
code = String.new
|
65
79
|
partial_tokens = []
|
66
80
|
unprocessed_tokens = []
|
@@ -106,30 +120,78 @@ class RubyLex
|
|
106
120
|
end
|
107
121
|
end
|
108
122
|
|
109
|
-
|
123
|
+
ERROR_TOKENS = [
|
124
|
+
:on_parse_error,
|
125
|
+
:compile_error,
|
126
|
+
:on_assign_error,
|
127
|
+
:on_alias_error,
|
128
|
+
:on_class_name_error,
|
129
|
+
:on_param_error
|
130
|
+
]
|
131
|
+
|
132
|
+
def self.ripper_lex_without_warning(code)
|
110
133
|
verbose, $VERBOSE = $VERBOSE, nil
|
111
134
|
tokens = nil
|
112
|
-
|
113
|
-
|
135
|
+
compile_with_errors_suppressed(code) do |inner_code, line_no|
|
136
|
+
lexer = Ripper::Lexer.new(inner_code, '-', line_no)
|
137
|
+
if lexer.respond_to?(:scan) # Ruby 2.7+
|
138
|
+
tokens = []
|
139
|
+
pos_to_index = {}
|
140
|
+
lexer.scan.each do |t|
|
141
|
+
if pos_to_index.has_key?(t[0])
|
142
|
+
index = pos_to_index[t[0]]
|
143
|
+
found_tk = tokens[index]
|
144
|
+
if ERROR_TOKENS.include?(found_tk[1]) && !ERROR_TOKENS.include?(t[1])
|
145
|
+
tokens[index] = t
|
146
|
+
end
|
147
|
+
else
|
148
|
+
pos_to_index[t[0]] = tokens.size
|
149
|
+
tokens << t
|
150
|
+
end
|
151
|
+
end
|
152
|
+
else
|
153
|
+
tokens = lexer.parse
|
154
|
+
end
|
114
155
|
end
|
115
|
-
$VERBOSE = verbose
|
116
156
|
tokens
|
157
|
+
ensure
|
158
|
+
$VERBOSE = verbose
|
159
|
+
end
|
160
|
+
|
161
|
+
def find_prev_spaces(line_index)
|
162
|
+
return 0 if @tokens.size == 0
|
163
|
+
md = @tokens[0][2].match(/(\A +)/)
|
164
|
+
prev_spaces = md.nil? ? 0 : md[1].count(' ')
|
165
|
+
line_count = 0
|
166
|
+
@tokens.each_with_index do |t, i|
|
167
|
+
if t[2].include?("\n")
|
168
|
+
line_count += t[2].count("\n")
|
169
|
+
if line_count >= line_index
|
170
|
+
return prev_spaces
|
171
|
+
end
|
172
|
+
if (@tokens.size - 1) > i
|
173
|
+
md = @tokens[i + 1][2].match(/(\A +)/)
|
174
|
+
prev_spaces = md.nil? ? 0 : md[1].count(' ')
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
prev_spaces
|
117
179
|
end
|
118
180
|
|
119
181
|
def set_auto_indent(context)
|
120
182
|
if @io.respond_to?(:auto_indent) and context.auto_indent_mode
|
121
183
|
@io.auto_indent do |lines, line_index, byte_pointer, is_newline|
|
122
184
|
if is_newline
|
123
|
-
|
124
|
-
prev_spaces =
|
125
|
-
@tokens = ripper_lex_without_warning(lines[0..line_index].join("\n"))
|
185
|
+
@tokens = self.class.ripper_lex_without_warning(lines[0..line_index].join("\n"))
|
186
|
+
prev_spaces = find_prev_spaces(line_index)
|
126
187
|
depth_difference = check_newline_depth_difference
|
188
|
+
depth_difference = 0 if depth_difference < 0
|
127
189
|
prev_spaces + depth_difference * 2
|
128
190
|
else
|
129
191
|
code = line_index.zero? ? '' : lines[0..(line_index - 1)].map{ |l| l + "\n" }.join
|
130
192
|
last_line = lines[line_index]&.byteslice(0, byte_pointer)
|
131
193
|
code += last_line if last_line
|
132
|
-
@tokens = ripper_lex_without_warning(code)
|
194
|
+
@tokens = self.class.ripper_lex_without_warning(code)
|
133
195
|
corresponding_token_depth = check_corresponding_token_depth
|
134
196
|
if corresponding_token_depth
|
135
197
|
corresponding_token_depth
|
@@ -142,7 +204,7 @@ class RubyLex
|
|
142
204
|
end
|
143
205
|
|
144
206
|
def check_state(code, tokens = nil)
|
145
|
-
tokens = ripper_lex_without_warning(code) unless tokens
|
207
|
+
tokens = self.class.ripper_lex_without_warning(code) unless tokens
|
146
208
|
ltype = process_literal_type(tokens)
|
147
209
|
indent = process_nesting_level(tokens)
|
148
210
|
continue = process_continue(tokens)
|
@@ -175,7 +237,10 @@ class RubyLex
|
|
175
237
|
throw :TERM_INPUT if @line == ''
|
176
238
|
else
|
177
239
|
@line_no += l.count("\n")
|
178
|
-
|
240
|
+
if l == "\n"
|
241
|
+
@exp_line_no += 1
|
242
|
+
next
|
243
|
+
end
|
179
244
|
@line.concat l
|
180
245
|
if @code_block_open or @ltype or @continue or @indent > 0
|
181
246
|
next
|
@@ -185,7 +250,7 @@ class RubyLex
|
|
185
250
|
@line.force_encoding(@io.encoding)
|
186
251
|
yield @line, @exp_line_no
|
187
252
|
end
|
188
|
-
|
253
|
+
raise TerminateLineInput if @io.eof?
|
189
254
|
@line = ''
|
190
255
|
@exp_line_no = @line_no
|
191
256
|
|
@@ -205,7 +270,7 @@ class RubyLex
|
|
205
270
|
end
|
206
271
|
code = @line + (line.nil? ? '' : line)
|
207
272
|
code.gsub!(/\s*\z/, '').concat("\n")
|
208
|
-
@tokens = ripper_lex_without_warning(code)
|
273
|
+
@tokens = self.class.ripper_lex_without_warning(code)
|
209
274
|
@continue = process_continue
|
210
275
|
@code_block_open = check_code_block(code)
|
211
276
|
@indent = process_nesting_level
|
@@ -226,8 +291,9 @@ class RubyLex
|
|
226
291
|
return true
|
227
292
|
elsif tokens.size >= 1 and tokens[-1][1] == :on_heredoc_end # "EOH\n"
|
228
293
|
return false
|
229
|
-
elsif tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and tokens[-2][3].anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME)
|
294
|
+
elsif tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and tokens[-2][3].anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME) and tokens[-2][2] !~ /\A\.\.\.?\z/
|
230
295
|
# end of literal except for regexp
|
296
|
+
# endless range at end of line is not a continue
|
231
297
|
return true
|
232
298
|
end
|
233
299
|
false
|
@@ -360,14 +426,8 @@ class RubyLex
|
|
360
426
|
next if index > 0 and tokens[index - 1][3].allbits?(Ripper::EXPR_FNAME)
|
361
427
|
case t[2]
|
362
428
|
when 'do'
|
363
|
-
|
364
|
-
|
365
|
-
indent += 1
|
366
|
-
else
|
367
|
-
# while cond do; end # also "until" or "for"
|
368
|
-
# This "do" doesn't increment indent because "while" already
|
369
|
-
# incremented.
|
370
|
-
end
|
429
|
+
syntax_of_do = take_corresponding_syntax_to_kw_do(tokens, index)
|
430
|
+
indent += 1 if syntax_of_do == :method_calling
|
371
431
|
when 'def', 'case', 'for', 'begin', 'class', 'module'
|
372
432
|
indent += 1
|
373
433
|
when 'if', 'unless', 'while', 'until'
|
@@ -382,6 +442,83 @@ class RubyLex
|
|
382
442
|
indent
|
383
443
|
end
|
384
444
|
|
445
|
+
def is_method_calling?(tokens, index)
|
446
|
+
tk = tokens[index]
|
447
|
+
if tk[3].anybits?(Ripper::EXPR_CMDARG) and tk[1] == :on_ident
|
448
|
+
# The target method call to pass the block with "do".
|
449
|
+
return true
|
450
|
+
elsif tk[3].anybits?(Ripper::EXPR_ARG) and tk[1] == :on_ident
|
451
|
+
non_sp_index = tokens[0..(index - 1)].rindex{ |t| t[1] != :on_sp }
|
452
|
+
if non_sp_index
|
453
|
+
prev_tk = tokens[non_sp_index]
|
454
|
+
if prev_tk[3].anybits?(Ripper::EXPR_DOT) and prev_tk[1] == :on_period
|
455
|
+
# The target method call with receiver to pass the block with "do".
|
456
|
+
return true
|
457
|
+
end
|
458
|
+
end
|
459
|
+
end
|
460
|
+
false
|
461
|
+
end
|
462
|
+
|
463
|
+
def take_corresponding_syntax_to_kw_do(tokens, index)
|
464
|
+
syntax_of_do = nil
|
465
|
+
# Finding a syntax correnponding to "do".
|
466
|
+
index.downto(0) do |i|
|
467
|
+
tk = tokens[i]
|
468
|
+
# In "continue", the token isn't the corresponding syntax to "do".
|
469
|
+
non_sp_index = tokens[0..(i - 1)].rindex{ |t| t[1] != :on_sp }
|
470
|
+
first_in_fomula = false
|
471
|
+
if non_sp_index.nil?
|
472
|
+
first_in_fomula = true
|
473
|
+
elsif [:on_ignored_nl, :on_nl, :on_comment].include?(tokens[non_sp_index][1])
|
474
|
+
first_in_fomula = true
|
475
|
+
end
|
476
|
+
if is_method_calling?(tokens, i)
|
477
|
+
syntax_of_do = :method_calling
|
478
|
+
break if first_in_fomula
|
479
|
+
elsif tk[1] == :on_kw && %w{while until for}.include?(tk[2])
|
480
|
+
# A loop syntax in front of "do" found.
|
481
|
+
#
|
482
|
+
# while cond do # also "until" or "for"
|
483
|
+
# end
|
484
|
+
#
|
485
|
+
# This "do" doesn't increment indent because the loop syntax already
|
486
|
+
# incremented.
|
487
|
+
syntax_of_do = :loop_syntax
|
488
|
+
break if first_in_fomula
|
489
|
+
end
|
490
|
+
end
|
491
|
+
syntax_of_do
|
492
|
+
end
|
493
|
+
|
494
|
+
def is_the_in_correspond_to_a_for(tokens, index)
|
495
|
+
syntax_of_in = nil
|
496
|
+
# Finding a syntax correnponding to "do".
|
497
|
+
index.downto(0) do |i|
|
498
|
+
tk = tokens[i]
|
499
|
+
# In "continue", the token isn't the corresponding syntax to "do".
|
500
|
+
non_sp_index = tokens[0..(i - 1)].rindex{ |t| t[1] != :on_sp }
|
501
|
+
first_in_fomula = false
|
502
|
+
if non_sp_index.nil?
|
503
|
+
first_in_fomula = true
|
504
|
+
elsif [:on_ignored_nl, :on_nl, :on_comment].include?(tokens[non_sp_index][1])
|
505
|
+
first_in_fomula = true
|
506
|
+
end
|
507
|
+
if tk[1] == :on_kw && tk[2] == 'for'
|
508
|
+
# A loop syntax in front of "do" found.
|
509
|
+
#
|
510
|
+
# while cond do # also "until" or "for"
|
511
|
+
# end
|
512
|
+
#
|
513
|
+
# This "do" doesn't increment indent because the loop syntax already
|
514
|
+
# incremented.
|
515
|
+
syntax_of_in = :for
|
516
|
+
end
|
517
|
+
break if first_in_fomula
|
518
|
+
end
|
519
|
+
syntax_of_in
|
520
|
+
end
|
521
|
+
|
385
522
|
def check_newline_depth_difference
|
386
523
|
depth_difference = 0
|
387
524
|
open_brace_on_line = 0
|
@@ -410,7 +547,7 @@ class RubyLex
|
|
410
547
|
|
411
548
|
case t[1]
|
412
549
|
when :on_ignored_nl, :on_nl, :on_comment
|
413
|
-
if index != (@tokens.size - 1)
|
550
|
+
if index != (@tokens.size - 1) and in_oneliner_def != :BODY
|
414
551
|
depth_difference = 0
|
415
552
|
open_brace_on_line = 0
|
416
553
|
end
|
@@ -428,14 +565,8 @@ class RubyLex
|
|
428
565
|
next if index > 0 and @tokens[index - 1][3].allbits?(Ripper::EXPR_FNAME)
|
429
566
|
case t[2]
|
430
567
|
when 'do'
|
431
|
-
|
432
|
-
|
433
|
-
depth_difference += 1
|
434
|
-
else
|
435
|
-
# while cond do; end # also "until" or "for"
|
436
|
-
# This "do" doesn't increment indent because "while" already
|
437
|
-
# incremented.
|
438
|
-
end
|
568
|
+
syntax_of_do = take_corresponding_syntax_to_kw_do(@tokens, index)
|
569
|
+
depth_difference += 1 if syntax_of_do == :method_calling
|
439
570
|
when 'def', 'case', 'for', 'begin', 'class', 'module'
|
440
571
|
depth_difference += 1
|
441
572
|
when 'if', 'unless', 'while', 'until', 'rescue'
|
@@ -443,8 +574,14 @@ class RubyLex
|
|
443
574
|
unless t[3].allbits?(Ripper::EXPR_LABEL)
|
444
575
|
depth_difference += 1
|
445
576
|
end
|
446
|
-
when 'else', 'elsif', 'ensure', 'when'
|
577
|
+
when 'else', 'elsif', 'ensure', 'when'
|
447
578
|
depth_difference += 1
|
579
|
+
when 'in'
|
580
|
+
unless is_the_in_correspond_to_a_for(@tokens, index)
|
581
|
+
depth_difference += 1
|
582
|
+
end
|
583
|
+
when 'end'
|
584
|
+
depth_difference -= 1
|
448
585
|
end
|
449
586
|
end
|
450
587
|
end
|
@@ -488,11 +625,13 @@ class RubyLex
|
|
488
625
|
|
489
626
|
case t[1]
|
490
627
|
when :on_ignored_nl, :on_nl, :on_comment
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
628
|
+
if in_oneliner_def != :BODY
|
629
|
+
corresponding_token_depth = nil
|
630
|
+
spaces_at_line_head = 0
|
631
|
+
is_first_spaces_of_line = true
|
632
|
+
is_first_printable_of_line = true
|
633
|
+
open_brace_on_line = 0
|
634
|
+
end
|
496
635
|
next
|
497
636
|
when :on_sp
|
498
637
|
spaces_at_line_head = t[2].count(' ') if is_first_spaces_of_line
|
@@ -514,7 +653,12 @@ class RubyLex
|
|
514
653
|
when :on_kw
|
515
654
|
next if index > 0 and @tokens[index - 1][3].allbits?(Ripper::EXPR_FNAME)
|
516
655
|
case t[2]
|
517
|
-
when '
|
656
|
+
when 'do'
|
657
|
+
syntax_of_do = take_corresponding_syntax_to_kw_do(@tokens, index)
|
658
|
+
if syntax_of_do == :method_calling
|
659
|
+
spaces_of_nest.push(spaces_at_line_head)
|
660
|
+
end
|
661
|
+
when 'def', 'case', 'for', 'begin', 'class', 'module'
|
518
662
|
spaces_of_nest.push(spaces_at_line_head)
|
519
663
|
when 'rescue'
|
520
664
|
unless t[3].allbits?(Ripper::EXPR_LABEL)
|
@@ -609,5 +753,50 @@ class RubyLex
|
|
609
753
|
nil
|
610
754
|
end
|
611
755
|
end
|
756
|
+
|
757
|
+
def check_termination_in_prev_line(code)
|
758
|
+
tokens = self.class.ripper_lex_without_warning(code)
|
759
|
+
past_first_newline = false
|
760
|
+
index = tokens.rindex do |t|
|
761
|
+
# traverse first token before last line
|
762
|
+
if past_first_newline
|
763
|
+
if t.tok.include?("\n")
|
764
|
+
true
|
765
|
+
end
|
766
|
+
elsif t.tok.include?("\n")
|
767
|
+
past_first_newline = true
|
768
|
+
false
|
769
|
+
else
|
770
|
+
false
|
771
|
+
end
|
772
|
+
end
|
773
|
+
if index
|
774
|
+
first_token = nil
|
775
|
+
last_line_tokens = tokens[(index + 1)..(tokens.size - 1)]
|
776
|
+
last_line_tokens.each do |t|
|
777
|
+
unless [:on_sp, :on_ignored_sp, :on_comment].include?(t.event)
|
778
|
+
first_token = t
|
779
|
+
break
|
780
|
+
end
|
781
|
+
end
|
782
|
+
if first_token.nil?
|
783
|
+
return false
|
784
|
+
elsif first_token && first_token.state == Ripper::EXPR_DOT
|
785
|
+
return false
|
786
|
+
else
|
787
|
+
tokens_without_last_line = tokens[0..index]
|
788
|
+
ltype = process_literal_type(tokens_without_last_line)
|
789
|
+
indent = process_nesting_level(tokens_without_last_line)
|
790
|
+
continue = process_continue(tokens_without_last_line)
|
791
|
+
code_block_open = check_code_block(tokens_without_last_line.map(&:tok).join(''), tokens_without_last_line)
|
792
|
+
if ltype or indent > 0 or continue or code_block_open
|
793
|
+
return false
|
794
|
+
else
|
795
|
+
return last_line_tokens.map(&:tok).join('')
|
796
|
+
end
|
797
|
+
end
|
798
|
+
end
|
799
|
+
false
|
800
|
+
end
|
612
801
|
end
|
613
802
|
# :startdoc:
|