irb 1.3.0 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +7 -0
- data/irb.gemspec +1 -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:
|