irb 1.8.1 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/irb/init.rb CHANGED
@@ -5,6 +5,41 @@
5
5
  #
6
6
 
7
7
  module IRB # :nodoc:
8
+ @CONF = {}
9
+ # Displays current configuration.
10
+ #
11
+ # Modifying the configuration is achieved by sending a message to IRB.conf.
12
+ #
13
+ # See IRB@Configuration for more information.
14
+ def IRB.conf
15
+ @CONF
16
+ end
17
+
18
+ def @CONF.inspect
19
+ array = []
20
+ for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
21
+ case k
22
+ when :MAIN_CONTEXT, :__TMP__EHV__
23
+ array.push format("CONF[:%s]=...myself...", k.id2name)
24
+ when :PROMPT
25
+ s = v.collect{
26
+ |kk, vv|
27
+ ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
28
+ format(":%s=>{%s}", kk.id2name, ss.join(", "))
29
+ }
30
+ array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
31
+ else
32
+ array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
33
+ end
34
+ end
35
+ array.join("\n")
36
+ end
37
+
38
+ # Returns the current version of IRB, including release version and last
39
+ # updated date.
40
+ def IRB.version
41
+ format("irb %s (%s)", @RELEASE_VERSION, @LAST_UPDATE_DATE)
42
+ end
8
43
 
9
44
  # initialize config
10
45
  def IRB.setup(ap_path, argv: ::ARGV)
@@ -28,6 +63,7 @@ module IRB # :nodoc:
28
63
  unless ap_path and @CONF[:AP_NAME]
29
64
  ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb")
30
65
  end
66
+ @CONF[:VERSION] = version
31
67
  @CONF[:AP_NAME] = File::basename(ap_path, ".rb")
32
68
 
33
69
  @CONF[:IRB_NAME] = "irb"
@@ -40,6 +76,7 @@ module IRB # :nodoc:
40
76
  @CONF[:USE_SINGLELINE] = false unless defined?(ReadlineInputMethod)
41
77
  @CONF[:USE_COLORIZE] = (nc = ENV['NO_COLOR']).nil? || nc.empty?
42
78
  @CONF[:USE_AUTOCOMPLETE] = ENV.fetch("IRB_USE_AUTOCOMPLETE", "true") != "false"
79
+ @CONF[:COMPLETOR] = :regexp
43
80
  @CONF[:INSPECT_MODE] = true
44
81
  @CONF[:USE_TRACER] = false
45
82
  @CONF[:USE_LOADER] = false
@@ -293,6 +330,10 @@ module IRB # :nodoc:
293
330
  @CONF[:USE_AUTOCOMPLETE] = true
294
331
  when "--noautocomplete"
295
332
  @CONF[:USE_AUTOCOMPLETE] = false
333
+ when "--regexp-completor"
334
+ @CONF[:COMPLETOR] = :regexp
335
+ when "--type-completor"
336
+ @CONF[:COMPLETOR] = :type
296
337
  when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/
297
338
  opt = $1 || argv.shift
298
339
  prompt_mode = opt.upcase.tr("-", "_").intern
@@ -11,6 +11,8 @@ require 'reline'
11
11
 
12
12
  module IRB
13
13
  class InputMethod
14
+ BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
15
+
14
16
  # The irb prompt associated with this input method
15
17
  attr_accessor :prompt
16
18
 
@@ -179,12 +181,20 @@ module IRB
179
181
  super
180
182
 
181
183
  @eof = false
184
+ @completor = RegexpCompletor.new
182
185
 
183
186
  if Readline.respond_to?("basic_word_break_characters=")
184
- Readline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
187
+ Readline.basic_word_break_characters = BASIC_WORD_BREAK_CHARACTERS
185
188
  end
186
189
  Readline.completion_append_character = nil
187
- Readline.completion_proc = IRB::InputCompletor::CompletionProc
190
+ Readline.completion_proc = ->(target) {
191
+ bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
192
+ @completor.completion_candidates('', target, '', bind: bind)
193
+ }
194
+ end
195
+
196
+ def completion_info
197
+ 'RegexpCompletor'
188
198
  end
189
199
 
190
200
  # Reads the next line from this input method.
@@ -224,17 +234,22 @@ module IRB
224
234
  HISTORY = Reline::HISTORY
225
235
  include HistorySavingAbility
226
236
  # Creates a new input method object using Reline
227
- def initialize
237
+ def initialize(completor)
228
238
  IRB.__send__(:set_encoding, Reline.encoding_system_needs.name, override: false)
229
239
 
230
- super
240
+ super()
231
241
 
232
242
  @eof = false
243
+ @completor = completor
233
244
 
234
- Reline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
245
+ Reline.basic_word_break_characters = BASIC_WORD_BREAK_CHARACTERS
235
246
  Reline.completion_append_character = nil
236
247
  Reline.completer_quote_characters = ''
237
- Reline.completion_proc = IRB::InputCompletor::CompletionProc
248
+ Reline.completion_proc = ->(target, preposing, postposing) {
249
+ bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
250
+ @completion_params = [preposing, target, postposing, bind]
251
+ @completor.completion_candidates(preposing, target, postposing, bind: bind)
252
+ }
238
253
  Reline.output_modifier_proc =
239
254
  if IRB.conf[:USE_COLORIZE]
240
255
  proc do |output, complete: |
@@ -247,18 +262,23 @@ module IRB
247
262
  Reline::Unicode.escape_for_print(output)
248
263
  end
249
264
  end
250
- Reline.dig_perfect_match_proc = IRB::InputCompletor::PerfectMatchedProc
265
+ Reline.dig_perfect_match_proc = ->(matched) { display_document(matched) }
251
266
  Reline.autocompletion = IRB.conf[:USE_AUTOCOMPLETE]
252
267
 
253
268
  if IRB.conf[:USE_AUTOCOMPLETE]
254
269
  begin
255
270
  require 'rdoc'
256
- Reline.add_dialog_proc(:show_doc, SHOW_DOC_DIALOG, Reline::DEFAULT_DIALOG_CONTEXT)
271
+ Reline.add_dialog_proc(:show_doc, show_doc_dialog_proc, Reline::DEFAULT_DIALOG_CONTEXT)
257
272
  rescue LoadError
258
273
  end
259
274
  end
260
275
  end
261
276
 
277
+ def completion_info
278
+ autocomplete_message = Reline.autocompletion ? 'Autocomplete' : 'Tab Complete'
279
+ "#{autocomplete_message}, #{@completor.inspect}"
280
+ end
281
+
262
282
  def check_termination(&block)
263
283
  @check_termination_proc = block
264
284
  end
@@ -271,100 +291,152 @@ module IRB
271
291
  @auto_indent_proc = block
272
292
  end
273
293
 
274
- SHOW_DOC_DIALOG = ->() {
275
- dialog.trap_key = nil
276
- alt_d = [
277
- [Reline::Key.new(nil, 0xE4, true)], # Normal Alt+d.
278
- [27, 100], # Normal Alt+d when convert-meta isn't used.
279
- [195, 164], # The "ä" that appears when Alt+d is pressed on xterm.
280
- [226, 136, 130] # The "∂" that appears when Alt+d in pressed on iTerm2.
281
- ]
294
+ def show_doc_dialog_proc
295
+ doc_namespace = ->(matched) {
296
+ preposing, _target, postposing, bind = @completion_params
297
+ @completor.doc_namespace(preposing, matched, postposing, bind: bind)
298
+ }
299
+ ->() {
300
+ dialog.trap_key = nil
301
+ alt_d = [
302
+ [Reline::Key.new(nil, 0xE4, true)], # Normal Alt+d.
303
+ [27, 100], # Normal Alt+d when convert-meta isn't used.
304
+ [195, 164], # The "ä" that appears when Alt+d is pressed on xterm.
305
+ [226, 136, 130] # The "∂" that appears when Alt+d in pressed on iTerm2.
306
+ ]
307
+
308
+ if just_cursor_moving and completion_journey_data.nil?
309
+ return nil
310
+ end
311
+ cursor_pos_to_render, result, pointer, autocomplete_dialog = context.pop(4)
312
+ return nil if result.nil? or pointer.nil? or pointer < 0
282
313
 
283
- if just_cursor_moving and completion_journey_data.nil?
284
- return nil
285
- end
286
- cursor_pos_to_render, result, pointer, autocomplete_dialog = context.pop(4)
287
- return nil if result.nil? or pointer.nil? or pointer < 0
288
- name = result[pointer]
289
- name = IRB::InputCompletor.retrieve_completion_data(name, doc_namespace: true)
314
+ name = doc_namespace.call(result[pointer])
315
+ show_easter_egg = name&.match?(/\ARubyVM/) && !ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
290
316
 
291
- options = {}
292
- options[:extra_doc_dirs] = IRB.conf[:EXTRA_DOC_DIRS] unless IRB.conf[:EXTRA_DOC_DIRS].empty?
293
- driver = RDoc::RI::Driver.new(options)
317
+ options = {}
318
+ options[:extra_doc_dirs] = IRB.conf[:EXTRA_DOC_DIRS] unless IRB.conf[:EXTRA_DOC_DIRS].empty?
319
+ driver = RDoc::RI::Driver.new(options)
294
320
 
295
- if key.match?(dialog.name)
296
- begin
297
- driver.display_names([name])
298
- rescue RDoc::RI::Driver::NotFoundError
321
+ if key.match?(dialog.name)
322
+ if show_easter_egg
323
+ IRB.__send__(:easter_egg)
324
+ else
325
+ begin
326
+ driver.display_names([name])
327
+ rescue RDoc::RI::Driver::NotFoundError
328
+ end
329
+ end
299
330
  end
300
- end
301
331
 
302
- begin
303
- name = driver.expand_name(name)
304
- rescue RDoc::RI::Driver::NotFoundError
305
- return nil
306
- rescue
307
- return nil # unknown error
308
- end
309
- doc = nil
310
- used_for_class = false
311
- if not name =~ /#|\./
312
- found, klasses, includes, extends = driver.classes_and_includes_and_extends_for(name)
313
- if not found.empty?
314
- doc = driver.class_document(name, found, klasses, includes, extends)
315
- used_for_class = true
316
- end
317
- end
318
- unless used_for_class
319
- doc = RDoc::Markup::Document.new
320
332
  begin
321
- driver.add_method(doc, name)
333
+ name = driver.expand_name(name)
322
334
  rescue RDoc::RI::Driver::NotFoundError
323
- doc = nil
335
+ return nil
324
336
  rescue
325
337
  return nil # unknown error
326
338
  end
327
- end
328
- return nil if doc.nil?
329
- width = 40
330
-
331
- right_x = cursor_pos_to_render.x + autocomplete_dialog.width
332
- if right_x + width > screen_width
333
- right_width = screen_width - (right_x + 1)
334
- left_x = autocomplete_dialog.column - width
335
- left_x = 0 if left_x < 0
336
- left_width = width > autocomplete_dialog.column ? autocomplete_dialog.column : width
337
- if right_width.positive? and left_width.positive?
338
- if right_width >= left_width
339
+ doc = nil
340
+ used_for_class = false
341
+ if not name =~ /#|\./
342
+ found, klasses, includes, extends = driver.classes_and_includes_and_extends_for(name)
343
+ if not found.empty?
344
+ doc = driver.class_document(name, found, klasses, includes, extends)
345
+ used_for_class = true
346
+ end
347
+ end
348
+ unless used_for_class
349
+ doc = RDoc::Markup::Document.new
350
+ begin
351
+ driver.add_method(doc, name)
352
+ rescue RDoc::RI::Driver::NotFoundError
353
+ doc = nil
354
+ rescue
355
+ return nil # unknown error
356
+ end
357
+ end
358
+ return nil if doc.nil?
359
+ width = 40
360
+
361
+ right_x = cursor_pos_to_render.x + autocomplete_dialog.width
362
+ if right_x + width > screen_width
363
+ right_width = screen_width - (right_x + 1)
364
+ left_x = autocomplete_dialog.column - width
365
+ left_x = 0 if left_x < 0
366
+ left_width = width > autocomplete_dialog.column ? autocomplete_dialog.column : width
367
+ if right_width.positive? and left_width.positive?
368
+ if right_width >= left_width
369
+ width = right_width
370
+ x = right_x
371
+ else
372
+ width = left_width
373
+ x = left_x
374
+ end
375
+ elsif right_width.positive? and left_width <= 0
339
376
  width = right_width
340
377
  x = right_x
341
- else
378
+ elsif right_width <= 0 and left_width.positive?
342
379
  width = left_width
343
380
  x = left_x
381
+ else # Both are negative width.
382
+ return nil
344
383
  end
345
- elsif right_width.positive? and left_width <= 0
346
- width = right_width
384
+ else
347
385
  x = right_x
348
- elsif right_width <= 0 and left_width.positive?
349
- width = left_width
350
- x = left_x
351
- else # Both are negative width.
352
- return nil
353
386
  end
387
+ formatter = RDoc::Markup::ToAnsi.new
388
+ formatter.width = width
389
+ dialog.trap_key = alt_d
390
+ mod_key = RUBY_PLATFORM.match?(/darwin/) ? "Option" : "Alt"
391
+ if show_easter_egg
392
+ type = STDOUT.external_encoding == Encoding::UTF_8 ? :unicode : :ascii
393
+ contents = IRB.send(:easter_egg_logo, type).split("\n")
394
+ message = "Press #{mod_key}+d to see more"
395
+ contents[0][0, message.size] = message
396
+ else
397
+ message = "Press #{mod_key}+d to read the full document"
398
+ contents = [message] + doc.accept(formatter).split("\n")
399
+ end
400
+ contents = contents.take(preferred_dialog_height)
401
+
402
+ y = cursor_pos_to_render.y
403
+ Reline::DialogRenderInfo.new(pos: Reline::CursorPos.new(x, y), contents: contents, width: width, bg_color: '49')
404
+ }
405
+ end
406
+
407
+ def display_document(matched, driver: nil)
408
+ begin
409
+ require 'rdoc'
410
+ rescue LoadError
411
+ return
412
+ end
413
+
414
+ if matched =~ /\A(?:::)?RubyVM/ and not ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
415
+ IRB.__send__(:easter_egg)
416
+ return
417
+ end
418
+
419
+ _target, preposing, postposing, bind = @completion_params
420
+ namespace = @completor.doc_namespace(preposing, matched, postposing, bind: bind)
421
+ return unless namespace
422
+
423
+ driver ||= RDoc::RI::Driver.new
424
+ if namespace.is_a?(Array)
425
+ out = RDoc::Markup::Document.new
426
+ namespace.each do |m|
427
+ begin
428
+ driver.add_method(out, m)
429
+ rescue RDoc::RI::Driver::NotFoundError
430
+ end
431
+ end
432
+ driver.display(out)
354
433
  else
355
- x = right_x
434
+ begin
435
+ driver.display_names([namespace])
436
+ rescue RDoc::RI::Driver::NotFoundError
437
+ end
356
438
  end
357
- formatter = RDoc::Markup::ToAnsi.new
358
- formatter.width = width
359
- dialog.trap_key = alt_d
360
- mod_key = RUBY_PLATFORM.match?(/darwin/) ? "Option" : "Alt"
361
- message = "Press #{mod_key}+d to read the full document"
362
- contents = [message] + doc.accept(formatter).split("\n")
363
- contents = contents.take(preferred_dialog_height)
364
-
365
- y = cursor_pos_to_render.y
366
- Reline::DialogRenderInfo.new(pos: Reline::CursorPos.new(x, y), contents: contents, width: width, bg_color: '49')
367
- }
439
+ end
368
440
 
369
441
  # Reads the next line from this input method.
370
442
  #
@@ -30,6 +30,9 @@ Usage: irb.rb [options] [programfile] [arguments]
30
30
  --nocolorize Don't use color-highlighting.
31
31
  --autocomplete Use auto-completion (default).
32
32
  --noautocomplete Don't use auto-completion.
33
+ --regexp-completor
34
+ Use regexp based completion (default).
35
+ --type-completor Use type based completion.
33
36
  --prompt prompt-mode, --prompt-mode prompt-mode
34
37
  Set prompt mode. Pre-defined prompt modes are:
35
38
  'default', 'classic', 'simple', 'inf-ruby', 'xmp', 'null'.
@@ -21,6 +21,9 @@ Usage: irb.rb [options] [programfile] [arguments]
21
21
  --nocolorize 色付けを利用しない.
22
22
  --autocomplete オートコンプリートを利用する.
23
23
  --noautocomplete オートコンプリートを利用しない.
24
+ --regexp-completor
25
+ 補完に正規表現を利用する.
26
+ --type-completor 補完に型情報を利用する.
24
27
  --prompt prompt-mode/--prompt-mode prompt-mode
25
28
  プロンプトモードを切替えます. 現在定義されているプ
26
29
  ロンプトモードは, default, simple, xmp, inf-rubyが
data/lib/irb/ruby-lex.rb CHANGED
@@ -42,14 +42,6 @@ module IRB
42
42
  end
43
43
  end
44
44
 
45
- attr_reader :line_no
46
-
47
- def initialize(context)
48
- @context = context
49
- @line_no = 1
50
- @prompt = nil
51
- end
52
-
53
45
  def self.compile_with_errors_suppressed(code, line_no: 1)
54
46
  begin
55
47
  result = yield code, line_no
@@ -67,10 +59,6 @@ module IRB
67
59
  result
68
60
  end
69
61
 
70
- def set_prompt(&block)
71
- @prompt = block
72
- end
73
-
74
62
  ERROR_TOKENS = [
75
63
  :on_parse_error,
76
64
  :compile_error,
@@ -116,9 +104,9 @@ module IRB
116
104
  interpolated
117
105
  end
118
106
 
119
- def self.ripper_lex_without_warning(code, context: nil)
107
+ def self.ripper_lex_without_warning(code, local_variables: [])
120
108
  verbose, $VERBOSE = $VERBOSE, nil
121
- lvars_code = generate_local_variables_assign_code(context&.local_variables || [])
109
+ lvars_code = generate_local_variables_assign_code(local_variables)
122
110
  original_code = code
123
111
  if lvars_code
124
112
  code = "#{lvars_code}\n#{code}"
@@ -146,20 +134,14 @@ module IRB
146
134
  $VERBOSE = verbose
147
135
  end
148
136
 
149
- def prompt(opens, continue, line_num_offset)
150
- ltype = ltype_from_open_tokens(opens)
151
- indent_level = calc_indent_level(opens)
152
- @prompt&.call(ltype, indent_level, opens.any? || continue, @line_no + line_num_offset)
153
- end
154
-
155
- def check_code_state(code)
156
- tokens = self.class.ripper_lex_without_warning(code, context: @context)
137
+ def check_code_state(code, local_variables:)
138
+ tokens = self.class.ripper_lex_without_warning(code, local_variables: local_variables)
157
139
  opens = NestingParser.open_tokens(tokens)
158
- [tokens, opens, code_terminated?(code, tokens, opens)]
140
+ [tokens, opens, code_terminated?(code, tokens, opens, local_variables: local_variables)]
159
141
  end
160
142
 
161
- def code_terminated?(code, tokens, opens)
162
- case check_code_syntax(code)
143
+ def code_terminated?(code, tokens, opens, local_variables:)
144
+ case check_code_syntax(code, local_variables: local_variables)
163
145
  when :unrecoverable_error
164
146
  true
165
147
  when :recoverable_error
@@ -171,16 +153,7 @@ module IRB
171
153
  end
172
154
  end
173
155
 
174
- def save_prompt_to_context_io(opens, continue, line_num_offset)
175
- # Implicitly saves prompt string to `@context.io.prompt`. This will be used in the next `@input.call`.
176
- prompt(opens, continue, line_num_offset)
177
- end
178
-
179
- def increase_line_no(addition)
180
- @line_no += addition
181
- end
182
-
183
- def assignment_expression?(code)
156
+ def assignment_expression?(code, local_variables:)
184
157
  # Try to parse the code and check if the last of possibly multiple
185
158
  # expressions is an assignment type.
186
159
 
@@ -190,7 +163,7 @@ module IRB
190
163
  # array of parsed expressions. The first element of each expression is the
191
164
  # expression's type.
192
165
  verbose, $VERBOSE = $VERBOSE, nil
193
- code = "#{RubyLex.generate_local_variables_assign_code(@context.local_variables) || 'nil;'}\n#{code}"
166
+ code = "#{RubyLex.generate_local_variables_assign_code(local_variables) || 'nil;'}\n#{code}"
194
167
  # Get the last node_type of the line. drop(1) is to ignore the local_variables_assign_code part.
195
168
  node_type = Ripper.sexp(code)&.dig(1)&.drop(1)&.dig(-1, 0)
196
169
  ASSIGNMENT_NODE_TYPES.include?(node_type)
@@ -222,8 +195,8 @@ module IRB
222
195
  false
223
196
  end
224
197
 
225
- def check_code_syntax(code)
226
- lvars_code = RubyLex.generate_local_variables_assign_code(@context.local_variables)
198
+ def check_code_syntax(code, local_variables:)
199
+ lvars_code = RubyLex.generate_local_variables_assign_code(local_variables)
227
200
  code = "#{lvars_code}\n#{code}"
228
201
 
229
202
  begin # check if parser error are available
@@ -455,8 +428,8 @@ module IRB
455
428
  end
456
429
  end
457
430
 
458
- def check_termination_in_prev_line(code)
459
- tokens = self.class.ripper_lex_without_warning(code, context: @context)
431
+ def check_termination_in_prev_line(code, local_variables:)
432
+ tokens = self.class.ripper_lex_without_warning(code, local_variables: local_variables)
460
433
  past_first_newline = false
461
434
  index = tokens.rindex do |t|
462
435
  # traverse first token before last line
@@ -486,7 +459,7 @@ module IRB
486
459
  tokens_without_last_line = tokens[0..index]
487
460
  code_without_last_line = tokens_without_last_line.map(&:tok).join
488
461
  opens_without_last_line = NestingParser.open_tokens(tokens_without_last_line)
489
- if code_terminated?(code_without_last_line, tokens_without_last_line, opens_without_last_line)
462
+ if code_terminated?(code_without_last_line, tokens_without_last_line, opens_without_last_line, local_variables: local_variables)
490
463
  return last_line_tokens.map(&:tok).join
491
464
  end
492
465
  end
data/lib/irb/ruby_logo.aa CHANGED
@@ -1,3 +1,4 @@
1
+ TYPE: LARGE
1
2
 
2
3
  -+smJYYN?mm-
3
4
  HB"BBYT TQg NggT
@@ -35,3 +36,45 @@
35
36
  m7 NW H N HSVO1z=?11-
36
37
  NgTH bB kH WBHWWHBHWmQgg&gggggNNN
37
38
  NNggggggNN
39
+ TYPE: ASCII
40
+ ,,,;;;;''''';;;'';,
41
+ ,,;'' ';;,;;; ',
42
+ ,,'' ;;'';'''';;;;;;
43
+ ,;' ;; ',, ;
44
+ ,;' ,;' ';, ;
45
+ ;' ,;; ',,,;
46
+ ,' ,;;,,,,,,,,,,,;;;;
47
+ ;' ;;';;;; ,;;
48
+ ;' ,;' ;; '',, ,;;;
49
+ ;; ,;' ; '';, ,; ;'
50
+ ;; ,;;' ;; ;; ;;
51
+ ;;, ,,;;' ; ;'; ;;
52
+ ;';;,,,,;;;;;;;,,, ;; ,' ; ;;
53
+ ; ;;''' ,;'; ''';,,, ; ,;' ;;;;
54
+ ;;;;, ; '; ''';;;' ';;;
55
+ ;'; ;, ;' '; ,;' ', ;;;
56
+ ;;; ; ,; '; ,,' ',, ;;
57
+ ;;; '; ;' ';,,'' ';,;;
58
+ '; ';,; ,,;''''''''';;;;;;,,;;;
59
+ ';,,;;,,;;;;;;;;;;''''''''''''''
60
+ TYPE: UNICODE
61
+ ⣀⣤⣴⣾⣿⣿⣿⡛⠛⠛⠛⠛⣻⣿⠿⠛⠛⠶⣤⡀
62
+ ⣀⣴⠾⠛⠉⠁ ⠙⣿⣶⣤⣶⣟⣉ ⠈⠻⣦
63
+ ⣀⣴⠟⠋ ⢸⣿⠟⠻⣯⡙⠛⠛⠛⠶⠶⠶⢶⣽⣇
64
+ ⣠⡾⠋⠁ ⣾⡿ ⠈⠛⢦⣄ ⣿
65
+ ⣠⡾⠋ ⣰⣿⠃ ⠙⠷⣤⡀ ⣿
66
+ ⢀⡾⠋ ⣰⣿⡏ ⠈⠻⣦⣄⢠⣿
67
+ ⣰⠟⠁ ⣴⣿⣿⣁⣀⣠⣤⣤⣤⣤⣤⣤⣤⣴⠶⠿⣿⡏
68
+ ⣼⠏ ⢀⣾⣿⠟⣿⠿⣯⣍⠁ ⣰⣿⡇
69
+ ⢀⣼⠋ ⢀⣴⣿⠟⠁ ⢸⡇ ⠙⠻⢦⣄⡀ ⢠⡿⣿⡇
70
+ ⢀⣾⡏ ⢀⣴⣿⠟⠁ ⣿ ⠉⠻⢶⣄⡀⣰⡟ ⣿⠃
71
+ ⣾⣿⠁ ⣠⣶⡿⠋⠁ ⢹⡇ ⠈⣿⡏ ⢸⣿
72
+ ⣿⣿⡆ ⢀⣠⣴⣿⡿⠋ ⠈⣿ ⢀⡾⠋⣿ ⢸⣿
73
+ ⣿⠸⣿⣶⣤⣤⣤⣤⣶⣾⠿⠿⣿⣿⠶⣤⣤⣀⡀ ⢹⡇ ⣴⠟⠁ ⣿⡀⢸⣿
74
+ ⣿⢀⣿⣟⠛⠋⠉⠁ ⢰⡟⠹⣧ ⠈⠉⠛⠻⠶⢦⣤⣀⡀ ⠈⣿ ⣠⡾⠃ ⢸⡇⢸⡇
75
+ ⣿⣾⣿⢿⡄ ⣿⠁ ⠘⣧ ⠉⠙⠛⠷⣿⣿⡋ ⠸⣇⣸⡇
76
+ ⣿⠃⣿⠈⢿⡄ ⣸⠇ ⠘⣧ ⢀⣤⠾⠋⠈⠻⣦⡀ ⣿⣿⡇
77
+ ⣿⢸⡏ ⠈⣷⡀ ⢠⡿ ⠘⣧⡀ ⣠⡴⠟⠁ ⠈⠻⣦⣀ ⢿⣿⠁
78
+ ⢻⣾⡇ ⠘⣷ ⣼⠃ ⠘⣷⣠⣴⠟⠋ ⠙⢷⣄⢸⣿
79
+ ⠻⣧⡀ ⠘⣧⣰⡏ ⢀⣠⣤⠶⠛⠉⠛⠛⠛⠛⠛⠛⠻⢶⣶⣶⣶⣶⣶⣤⣤⣽⣿⣿
80
+ ⠈⠛⠷⢦⣤⣽⣿⣥⣤⣶⣶⡿⠿⠿⠶⠶⠶⠶⠾⠛⠛⠛⠛⠛⠛⠛⠋⠉⠉⠉⠉⠉⠉⠁
@@ -43,7 +43,7 @@ module IRB
43
43
  private
44
44
 
45
45
  def find_end(file, first_line)
46
- lex = RubyLex.new(@irb_context)
46
+ lex = RubyLex.new
47
47
  lines = File.read(file).lines[(first_line - 1)..-1]
48
48
  tokens = RubyLex.ripper_lex_without_warning(lines.join)
49
49
  prev_tokens = []
@@ -53,7 +53,7 @@ module IRB
53
53
  code = lines[0..lnum].join
54
54
  prev_tokens.concat chunk
55
55
  continue = lex.should_continue?(prev_tokens)
56
- syntax = lex.check_code_syntax(code)
56
+ syntax = lex.check_code_syntax(code, local_variables: [])
57
57
  if !continue && syntax == :valid
58
58
  return first_line + lnum
59
59
  end