irb 1.8.1 → 1.9.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.
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