irb 1.4.1 → 1.4.3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/irb/init.rb CHANGED
@@ -44,7 +44,7 @@ module IRB # :nodoc:
44
44
  @CONF[:IRB_RC] = nil
45
45
 
46
46
  @CONF[:USE_SINGLELINE] = false unless defined?(ReadlineInputMethod)
47
- @CONF[:USE_COLORIZE] = !ENV['NO_COLOR']
47
+ @CONF[:USE_COLORIZE] = (nc = ENV['NO_COLOR']).nil? || nc.empty?
48
48
  @CONF[:USE_AUTOCOMPLETE] = true
49
49
  @CONF[:INSPECT_MODE] = true
50
50
  @CONF[:USE_TRACER] = false
@@ -158,6 +158,11 @@ module IRB # :nodoc:
158
158
  @CONF[:LC_MESSAGES] = Locale.new
159
159
 
160
160
  @CONF[:AT_EXIT] = []
161
+
162
+ @CONF[:COMMAND_ALIASES] = {
163
+ :'$' => :show_source,
164
+ :'@' => :whereami,
165
+ }
161
166
  end
162
167
 
163
168
  def IRB.set_measure_callback(type = nil, arg = nil, &block)
@@ -255,8 +260,20 @@ module IRB # :nodoc:
255
260
  when "--nosingleline", "--noreadline"
256
261
  @CONF[:USE_SINGLELINE] = false
257
262
  when "--multiline", "--reidline"
263
+ if opt == "--reidline"
264
+ warn <<~MSG.strip
265
+ --reidline is deprecated, please use --multiline instead.
266
+ MSG
267
+ end
268
+
258
269
  @CONF[:USE_MULTILINE] = true
259
270
  when "--nomultiline", "--noreidline"
271
+ if opt == "--noreidline"
272
+ warn <<~MSG.strip
273
+ --noreidline is deprecated, please use --nomultiline instead.
274
+ MSG
275
+ end
276
+
260
277
  @CONF[:USE_MULTILINE] = false
261
278
  when /^--extra-doc-dir(?:=(.+))?/
262
279
  opt = $1 || argv.shift
@@ -289,6 +306,10 @@ module IRB # :nodoc:
289
306
  @CONF[:PROMPT_MODE] = prompt_mode
290
307
  when "--noprompt"
291
308
  @CONF[:PROMPT_MODE] = :NULL
309
+ when "--script"
310
+ noscript = false
311
+ when "--noscript"
312
+ noscript = true
292
313
  when "--inf-ruby-mode"
293
314
  @CONF[:PROMPT_MODE] = :INF_RUBY
294
315
  when "--sample-book-mode", "--simple-prompt"
@@ -309,16 +330,20 @@ module IRB # :nodoc:
309
330
  IRB.print_usage
310
331
  exit 0
311
332
  when "--"
312
- if opt = argv.shift
333
+ if !noscript && (opt = argv.shift)
313
334
  @CONF[:SCRIPT] = opt
314
335
  $0 = opt
315
336
  end
316
337
  break
317
- when /^-/
338
+ when /^-./
318
339
  fail UnrecognizedSwitch, opt
319
340
  else
320
- @CONF[:SCRIPT] = opt
321
- $0 = opt
341
+ if noscript
342
+ argv.unshift(opt)
343
+ else
344
+ @CONF[:SCRIPT] = opt
345
+ $0 = opt
346
+ end
322
347
  break
323
348
  end
324
349
  end
@@ -371,11 +396,9 @@ module IRB # :nodoc:
371
396
  end
372
397
  if xdg_config_home = ENV["XDG_CONFIG_HOME"]
373
398
  irb_home = File.join(xdg_config_home, "irb")
374
- unless File.exist? irb_home
375
- require 'fileutils'
376
- FileUtils.mkdir_p irb_home
399
+ if File.directory?(irb_home)
400
+ yield proc{|rc| irb_home + "/irb#{rc}"}
377
401
  end
378
- yield proc{|rc| irb_home + "/irb#{rc}"}
379
402
  end
380
403
  if home = ENV["HOME"]
381
404
  yield proc{|rc| home+"/.irb#{rc}"}
@@ -14,7 +14,6 @@ require_relative 'magic-file'
14
14
  require_relative 'completion'
15
15
  require 'io/console'
16
16
  require 'reline'
17
- require 'rdoc'
18
17
 
19
18
  module IRB
20
19
  STDIN_FILE_NAME = "(line)" # :nodoc:
@@ -39,7 +38,7 @@ module IRB
39
38
  public :gets
40
39
 
41
40
  def winsize
42
- if instance_variable_defined?(:@stdout)
41
+ if instance_variable_defined?(:@stdout) && @stdout.tty?
43
42
  @stdout.winsize
44
43
  else
45
44
  [24, 80]
@@ -84,8 +83,7 @@ module IRB
84
83
  #
85
84
  # See IO#eof? for more information.
86
85
  def eof?
87
- rs, = IO.select([@stdin], [], [], 0.00001)
88
- if rs and rs[0]
86
+ if @stdin.wait_readable(0.00001)
89
87
  c = @stdin.getc
90
88
  result = c.nil? ? true : false
91
89
  @stdin.ungetc(c) unless c.nil?
@@ -139,7 +137,7 @@ module IRB
139
137
  # Creates a new input method object
140
138
  def initialize(file)
141
139
  super
142
- @io = IRB::MagicFile.open(file)
140
+ @io = file.is_a?(IO) ? file : IRB::MagicFile.open(file)
143
141
  @external_encoding = @io.external_encoding
144
142
  end
145
143
  # The file name of this input method, usually given during initialization.
@@ -263,7 +261,7 @@ module IRB
263
261
  end
264
262
  end
265
263
 
266
- class ReidlineInputMethod < InputMethod
264
+ class RelineInputMethod < InputMethod
267
265
  include Reline
268
266
 
269
267
  # Creates a new input method object using Reline
@@ -288,7 +286,8 @@ module IRB
288
286
  if IRB.conf[:USE_COLORIZE]
289
287
  proc do |output, complete: |
290
288
  next unless IRB::Color.colorable?
291
- IRB::Color.colorize_code(output, complete: complete)
289
+ lvars = IRB.CurrentContext&.local_variables || []
290
+ IRB::Color.colorize_code(output, complete: complete, local_variables: lvars)
292
291
  end
293
292
  else
294
293
  proc do |output|
@@ -297,8 +296,13 @@ module IRB
297
296
  end
298
297
  Reline.dig_perfect_match_proc = IRB::InputCompletor::PerfectMatchedProc
299
298
  Reline.autocompletion = IRB.conf[:USE_AUTOCOMPLETE]
299
+
300
300
  if IRB.conf[:USE_AUTOCOMPLETE]
301
- Reline.add_dialog_proc(:show_doc, SHOW_DOC_DIALOG, Reline::DEFAULT_DIALOG_CONTEXT)
301
+ begin
302
+ require 'rdoc'
303
+ Reline.add_dialog_proc(:show_doc, SHOW_DOC_DIALOG, Reline::DEFAULT_DIALOG_CONTEXT)
304
+ rescue LoadError
305
+ end
302
306
  end
303
307
  end
304
308
 
@@ -457,7 +461,7 @@ module IRB
457
461
  # For debug message
458
462
  def inspect
459
463
  config = Reline::Config.new
460
- str = "ReidlineInputMethod with Reline #{Reline::VERSION}"
464
+ str = "RelineInputMethod with Reline #{Reline::VERSION}"
461
465
  if config.respond_to?(:inputrc_path)
462
466
  inputrc_path = File.expand_path(config.inputrc_path)
463
467
  else
@@ -467,4 +471,13 @@ module IRB
467
471
  str
468
472
  end
469
473
  end
474
+
475
+ class ReidlineInputMethod < RelineInputMethod
476
+ def initialize
477
+ warn <<~MSG.strip
478
+ IRB::ReidlineInputMethod is deprecated, please use IRB::RelineInputMethod instead.
479
+ MSG
480
+ super
481
+ end
482
+ end
470
483
  end
data/lib/irb/inspector.rb CHANGED
@@ -108,18 +108,10 @@ module IRB # :nodoc:
108
108
 
109
109
  Inspector.def_inspector([false, :to_s, :raw]){|v| v.to_s}
110
110
  Inspector.def_inspector([:p, :inspect]){|v|
111
- result = v.inspect
112
- if IRB.conf[:MAIN_CONTEXT]&.use_colorize? && Color.inspect_colorable?(v)
113
- result = Color.colorize_code(result)
114
- end
115
- result
111
+ Color.colorize_code(v.inspect, colorable: Color.colorable? && Color.inspect_colorable?(v))
116
112
  }
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
113
+ Inspector.def_inspector([true, :pp, :pretty_inspect], proc{require_relative "color_printer"}){|v|
114
+ IRB::ColorPrinter.pp(v, '').chomp
123
115
  }
124
116
  Inspector.def_inspector([:yaml, :YAML], proc{require "yaml"}){|v|
125
117
  begin
data/lib/irb/lc/error.rb CHANGED
@@ -10,8 +10,9 @@
10
10
  #
11
11
  #
12
12
 
13
- # :stopdoc:
14
13
  module IRB
14
+ # :stopdoc:
15
+
15
16
  class UnrecognizedSwitch < StandardError
16
17
  def initialize(val)
17
18
  super("Unrecognized switch: #{val}")
@@ -47,11 +48,6 @@ module IRB
47
48
  super("No such job(#{val}).")
48
49
  end
49
50
  end
50
- class CantShiftToMultiIrbMode < StandardError
51
- def initialize
52
- super("Can't shift to multi irb mode.")
53
- end
54
- end
55
51
  class CantChangeBinding < StandardError
56
52
  def initialize(val)
57
53
  super("Can't change binding to (#{val}).")
@@ -67,5 +63,6 @@ module IRB
67
63
  super("Define illegal RC_NAME_GENERATOR.")
68
64
  end
69
65
  end
66
+
67
+ # :startdoc:
70
68
  end
71
- # :startdoc:
@@ -1,61 +1,51 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # irb/lc/help-message.rb -
4
- # $Release Version: 0.9.6$
5
- # $Revision$
6
- # by Keiju ISHITSUKA(keiju@ruby-lang.org)
7
- #
8
- # --
9
- #
10
- #
11
- #
12
1
  Usage: irb.rb [options] [programfile] [arguments]
13
- -f Suppress read of ~/.irbrc
14
- -d Set $DEBUG to true (same as `ruby -d')
15
- -r load-module Same as `ruby -r'
16
- -I path Specify $LOAD_PATH directory
17
- -U Same as `ruby -U`
18
- -E enc Same as `ruby -E`
19
- -w Same as `ruby -w`
20
- -W[level=2] Same as `ruby -W`
2
+ -f Don't initialize from configuration file.
3
+ -d Set $DEBUG and $VERBOSE to true (same as 'ruby -d').
4
+ -r load-module Require load-module (same as 'ruby -r').
5
+ -I path Specify $LOAD_PATH directory (same as 'ruby -I').
6
+ -U Set external and internal encodings to UTF-8.
7
+ -E ex[:in] Set default external (ex) and internal (in) encodings
8
+ (same as 'ruby -E').
9
+ -w Suppress warnings (same as 'ruby -w').
10
+ -W[level=2] Set warning level: 0=silence, 1=medium, 2=verbose
11
+ (same as 'ruby -W').
21
12
  --context-mode n Set n[0-4] to method to create Binding Object,
22
- when new workspace was created
23
- --extra-doc-dir Add an extra doc dir for the doc dialog
24
- --echo Show result (default)
25
- --noecho Don't show result
13
+ when new workspace was created.
14
+ --extra-doc-dir Add an extra doc dir for the doc dialog.
15
+ --echo Show result (default).
16
+ --noecho Don't show result.
26
17
  --echo-on-assignment
27
- Show result on assignment
18
+ Show result on assignment.
28
19
  --noecho-on-assignment
29
- Don't show result on assignment
20
+ Don't show result on assignment.
30
21
  --truncate-echo-on-assignment
31
- Show truncated result on assignment (default)
32
- --inspect Use `inspect' for output
33
- --noinspect Don't use inspect for output
34
- --multiline Use multiline editor module
35
- --nomultiline Don't use multiline editor module
36
- --singleline Use singleline editor module
37
- --nosingleline Don't use singleline editor module
38
- --colorize Use colorization
39
- --nocolorize Don't use colorization
40
- --autocomplete Use autocompletion
41
- --noautocomplete Don't use autocompletion
42
- --prompt prompt-mode/--prompt-mode prompt-mode
43
- Switch prompt mode. Pre-defined prompt modes are
44
- `default', `simple', `xmp' and `inf-ruby'
22
+ Show truncated result on assignment (default).
23
+ --inspect Use 'inspect' for output.
24
+ --noinspect Don't use 'inspect' for output.
25
+ --multiline Use multiline editor module.
26
+ --nomultiline Don't use multiline editor module (default).
27
+ --singleline Use single line editor module.
28
+ --nosingleline Don't use single line editor module (default).
29
+ --colorize Use color-highlighting (default).
30
+ --nocolorize Don't use color-highlighting.
31
+ --autocomplete Use auto-completion (default).
32
+ --noautocomplete Don't use auto-completion.
33
+ --prompt prompt-mode, --prompt-mode prompt-mode
34
+ Set prompt mode. Pre-defined prompt modes are:
35
+ 'default', 'classic', 'simple', 'inf-ruby', 'xmp', 'null'.
45
36
  --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
46
37
  Suppresses --multiline and --singleline.
47
- --sample-book-mode/--simple-prompt
48
- Simple prompt mode
49
- --noprompt No prompt mode
38
+ --sample-book-mode, --simple-prompt
39
+ Set prompt mode to 'simple'.
40
+ --noprompt Don't output prompt.
41
+ --script Script mode (default, treat first argument as script)
42
+ --noscript No script mode (leave arguments in argv)
50
43
  --single-irb Share self with sub-irb.
51
- --tracer Display trace for each execution of commands.
52
- --back-trace-limit n
53
- Display backtrace top n and tail n. The default
54
- value is 16.
55
- --verbose Show details
56
- --noverbose Don't show details
57
- -v, --version Print the version of irb
58
- -h, --help Print help
59
- -- Separate options of irb from the list of command-line args
60
-
61
- # vim:fileencoding=utf-8
44
+ --tracer Show stack trace for each command.
45
+ --back-trace-limit n[=16]
46
+ Display backtrace top n and bottom n.
47
+ --verbose Show details.
48
+ --noverbose Don't show details.
49
+ -v, --version Print the version of irb.
50
+ -h, --help Print help.
51
+ -- Separate options of irb from the list of command-line args.
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: false
2
- # :stopdoc:
3
2
  module IRB
3
+ # :stopdoc:
4
+
4
5
  class Locale
5
6
  @@legacy_encoding_alias_map = {
6
7
  'ujis' => Encoding::EUC_JP,
7
8
  'euc' => Encoding::EUC_JP
8
9
  }.freeze
9
10
  end
11
+
12
+ # :startdoc:
10
13
  end
11
- # :startdoc:
@@ -10,8 +10,9 @@
10
10
  #
11
11
  #
12
12
 
13
- # :stopdoc:
14
13
  module IRB
14
+ # :stopdoc:
15
+
15
16
  class UnrecognizedSwitch < StandardError
16
17
  def initialize(val)
17
18
  super("スイッチ(#{val})が分りません")
@@ -47,11 +48,6 @@ module IRB
47
48
  super("そのようなジョブ(#{val})はありません.")
48
49
  end
49
50
  end
50
- class CantShiftToMultiIrbMode < StandardError
51
- def initialize
52
- super("multi-irb modeに移れません.")
53
- end
54
- end
55
51
  class CantChangeBinding < StandardError
56
52
  def initialize(val)
57
53
  super("バインディング(#{val})に変更できません.")
@@ -67,6 +63,7 @@ module IRB
67
63
  super("RC_NAME_GENERATORが正しく定義されていません.")
68
64
  end
69
65
  end
66
+
67
+ # :startdoc:
70
68
  end
71
- # :startdoc:
72
69
  # vim:fileencoding=utf-8
@@ -1,13 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
- # irb/lc/ja/help-message.rb -
3
- # $Release Version: 0.9.6$
4
- # $Revision$
5
- # by Keiju ISHITSUKA(keiju@ruby-lang.org)
6
- #
7
- # --
8
- #
9
- #
10
- #
11
1
  Usage: irb.rb [options] [programfile] [arguments]
12
2
  -f ~/.irbrc を読み込まない.
13
3
  -d $DEBUG をtrueにする(ruby -d と同じ)
@@ -53,5 +43,3 @@ Usage: irb.rb [options] [programfile] [arguments]
53
43
  -v, --version irbのバージョンを表示する.
54
44
  -h, --help irb のヘルプを表示する.
55
45
  -- 以降のコマンドライン引数をオプションとして扱わない.
56
-
57
- # vim:fileencoding=utf-8
data/lib/irb/ruby-lex.rb CHANGED
@@ -48,7 +48,7 @@ class RubyLex
48
48
  end
49
49
 
50
50
  # io functions
51
- def set_input(io, p = nil, context: nil, &block)
51
+ def set_input(io, p = nil, context:, &block)
52
52
  @io = io
53
53
  if @io.respond_to?(:check_termination)
54
54
  @io.check_termination do |code|
@@ -65,6 +65,12 @@ class RubyLex
65
65
  false
66
66
  end
67
67
  else
68
+ # Accept any single-line input starting with a non-identifier alias (ex: @, $)
69
+ command = code.split(/\s/, 2).first
70
+ if context.symbol_alias(command)
71
+ next true
72
+ end
73
+
68
74
  code.gsub!(/\s*\z/, '').concat("\n")
69
75
  ltype, indent, continue, code_block_open = check_state(code, context: context)
70
76
  if ltype or indent > 0 or continue or code_block_open
@@ -136,41 +142,37 @@ class RubyLex
136
142
  :on_param_error
137
143
  ]
138
144
 
145
+ def self.generate_local_variables_assign_code(local_variables)
146
+ "#{local_variables.join('=')}=nil;" unless local_variables.empty?
147
+ end
148
+
139
149
  def self.ripper_lex_without_warning(code, context: nil)
140
150
  verbose, $VERBOSE = $VERBOSE, nil
141
- if context
142
- lvars = context&.workspace&.binding&.local_variables
143
- if lvars && !lvars.empty?
144
- code = "#{lvars.join('=')}=nil\n#{code}"
145
- line_no = 0
146
- else
147
- line_no = 1
148
- end
151
+ lvars_code = generate_local_variables_assign_code(context&.local_variables || [])
152
+ if lvars_code
153
+ code = "#{lvars_code}\n#{code}"
154
+ line_no = 0
155
+ else
156
+ line_no = 1
149
157
  end
150
- tokens = nil
158
+
151
159
  compile_with_errors_suppressed(code, line_no: line_no) do |inner_code, line_no|
152
160
  lexer = Ripper::Lexer.new(inner_code, '-', line_no)
153
161
  if lexer.respond_to?(:scan) # Ruby 2.7+
154
- tokens = []
155
- pos_to_index = {}
156
- lexer.scan.each do |t|
162
+ lexer.scan.each_with_object([]) do |t, tokens|
157
163
  next if t.pos.first == 0
158
- if pos_to_index.has_key?(t.pos)
159
- index = pos_to_index[t.pos]
160
- found_tk = tokens[index]
161
- if ERROR_TOKENS.include?(found_tk.event) && !ERROR_TOKENS.include?(t.event)
162
- tokens[index] = t
163
- end
164
+ prev_tk = tokens.last
165
+ position_overlapped = prev_tk && t.pos[0] == prev_tk.pos[0] && t.pos[1] < prev_tk.pos[1] + prev_tk.tok.bytesize
166
+ if position_overlapped
167
+ tokens[-1] = t if ERROR_TOKENS.include?(prev_tk.event) && !ERROR_TOKENS.include?(t.event)
164
168
  else
165
- pos_to_index[t.pos] = tokens.size
166
169
  tokens << t
167
170
  end
168
171
  end
169
172
  else
170
- tokens = lexer.parse.reject { |it| it.pos.first == 0 }
173
+ lexer.parse.reject { |it| it.pos.first == 0 }.sort_by(&:pos)
171
174
  end
172
175
  end
173
- tokens
174
176
  ensure
175
177
  $VERBOSE = verbose
176
178
  end
@@ -209,12 +211,7 @@ class RubyLex
209
211
  last_line = lines[line_index]&.byteslice(0, byte_pointer)
210
212
  code += last_line if last_line
211
213
  @tokens = self.class.ripper_lex_without_warning(code, context: context)
212
- corresponding_token_depth = check_corresponding_token_depth(lines, line_index)
213
- if corresponding_token_depth
214
- corresponding_token_depth
215
- else
216
- nil
217
- end
214
+ check_corresponding_token_depth(lines, line_index)
218
215
  end
219
216
  end
220
217
  end
@@ -225,6 +222,8 @@ class RubyLex
225
222
  ltype = process_literal_type(tokens)
226
223
  indent = process_nesting_level(tokens)
227
224
  continue = process_continue(tokens)
225
+ lvars_code = self.class.generate_local_variables_assign_code(context.local_variables)
226
+ code = "#{lvars_code}\n#{code}" if lvars_code
228
227
  code_block_open = check_code_block(code, tokens)
229
228
  [ltype, indent, continue, code_block_open]
230
229
  end
@@ -244,13 +243,13 @@ class RubyLex
244
243
  @code_block_open = false
245
244
  end
246
245
 
247
- def each_top_level_statement
246
+ def each_top_level_statement(context)
248
247
  initialize_input
249
248
  catch(:TERM_INPUT) do
250
249
  loop do
251
250
  begin
252
251
  prompt
253
- unless l = lex
252
+ unless l = lex(context)
254
253
  throw :TERM_INPUT if @line == ''
255
254
  else
256
255
  @line_no += l.count("\n")
@@ -280,18 +279,15 @@ class RubyLex
280
279
  end
281
280
  end
282
281
 
283
- def lex
282
+ def lex(context)
284
283
  line = @input.call
285
284
  if @io.respond_to?(:check_termination)
286
285
  return line # multiline
287
286
  end
288
287
  code = @line + (line.nil? ? '' : line)
289
288
  code.gsub!(/\s*\z/, '').concat("\n")
290
- @tokens = self.class.ripper_lex_without_warning(code)
291
- @continue = process_continue
292
- @code_block_open = check_code_block(code)
293
- @indent = process_nesting_level
294
- @ltype = process_literal_type
289
+ @tokens = self.class.ripper_lex_without_warning(code, context: context)
290
+ @ltype, @indent, @continue, @code_block_open = check_state(code, @tokens, context: context)
295
291
  line
296
292
  end
297
293
 
@@ -308,7 +304,7 @@ class RubyLex
308
304
  return true
309
305
  elsif tokens.size >= 1 and tokens[-1].event == :on_heredoc_end # "EOH\n"
310
306
  return false
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/
307
+ elsif tokens.size >= 2 and tokens[-2].state.anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME) and tokens[-2].tok !~ /\A\.\.\.?\z/
312
308
  # end of literal except for regexp
313
309
  # endless range at end of line is not a continue
314
310
  return true
@@ -389,21 +385,20 @@ class RubyLex
389
385
  $VERBOSE = verbose
390
386
  end
391
387
 
392
- if defined?(Ripper::EXPR_BEG)
393
- last_lex_state = tokens.last.state
394
- if last_lex_state.allbits?(Ripper::EXPR_BEG)
395
- return false
396
- elsif last_lex_state.allbits?(Ripper::EXPR_DOT)
397
- return true
398
- elsif last_lex_state.allbits?(Ripper::EXPR_CLASS)
399
- return true
400
- elsif last_lex_state.allbits?(Ripper::EXPR_FNAME)
401
- return true
402
- elsif last_lex_state.allbits?(Ripper::EXPR_VALUE)
403
- return true
404
- elsif last_lex_state.allbits?(Ripper::EXPR_ARG)
405
- return false
406
- end
388
+ last_lex_state = tokens.last.state
389
+
390
+ if last_lex_state.allbits?(Ripper::EXPR_BEG)
391
+ return false
392
+ elsif last_lex_state.allbits?(Ripper::EXPR_DOT)
393
+ return true
394
+ elsif last_lex_state.allbits?(Ripper::EXPR_CLASS)
395
+ return true
396
+ elsif last_lex_state.allbits?(Ripper::EXPR_FNAME)
397
+ return true
398
+ elsif last_lex_state.allbits?(Ripper::EXPR_VALUE)
399
+ return true
400
+ elsif last_lex_state.allbits?(Ripper::EXPR_ARG)
401
+ return false
407
402
  end
408
403
 
409
404
  false
@@ -718,6 +713,7 @@ class RubyLex
718
713
  i = 0
719
714
  start_token = []
720
715
  end_type = []
716
+ pending_heredocs = []
721
717
  while i < tokens.size
722
718
  t = tokens[i]
723
719
  case t.event
@@ -741,18 +737,27 @@ class RubyLex
741
737
  end
742
738
  end
743
739
  when :on_backtick
744
- start_token << t
745
- end_type << :on_tstring_end
740
+ if t.state.allbits?(Ripper::EXPR_BEG)
741
+ start_token << t
742
+ end_type << :on_tstring_end
743
+ end
746
744
  when :on_qwords_beg, :on_words_beg, :on_qsymbols_beg, :on_symbols_beg
747
745
  start_token << t
748
746
  end_type << :on_tstring_end
749
747
  when :on_heredoc_beg
750
- start_token << t
751
- end_type << :on_heredoc_end
748
+ pending_heredocs << t
749
+ end
750
+
751
+ if pending_heredocs.any? && t.tok.include?("\n")
752
+ pending_heredocs.reverse_each do |t|
753
+ start_token << t
754
+ end_type << :on_heredoc_end
755
+ end
756
+ pending_heredocs = []
752
757
  end
753
758
  i += 1
754
759
  end
755
- start_token.last.nil? ? nil : start_token.last
760
+ pending_heredocs.first || start_token.last
756
761
  end
757
762
 
758
763
  def process_literal_type(tokens = @tokens)
data/lib/irb/version.rb CHANGED
@@ -11,7 +11,7 @@
11
11
  #
12
12
 
13
13
  module IRB # :nodoc:
14
- VERSION = "1.4.1"
14
+ VERSION = "1.4.3"
15
15
  @RELEASE_VERSION = VERSION
16
- @LAST_UPDATE_DATE = "2021-12-25"
16
+ @LAST_UPDATE_DATE = "2022-11-17"
17
17
  end
data/lib/irb/workspace.rb CHANGED
@@ -158,27 +158,20 @@ EOF
158
158
  end
159
159
  end
160
160
 
161
- # NOT using #use_colorize? of IRB.conf[:MAIN_CONTEXT] because this method may be called before IRB::Irb#run
162
- use_colorize = IRB.conf.fetch(:USE_COLORIZE, true)
163
- if use_colorize
164
- lines = Color.colorize_code(code).lines
165
- else
166
- lines = code.lines
167
- end
161
+ lines = Color.colorize_code(code).lines
168
162
  pos -= 1
169
163
 
170
164
  start_pos = [pos - 5, 0].max
171
165
  end_pos = [pos + 5, lines.size - 1].min
172
166
 
173
- if use_colorize
174
- fmt = " %2s #{Color.colorize("%#{end_pos.to_s.length}d", [:BLUE, :BOLD])}: %s"
175
- else
176
- fmt = " %2s %#{end_pos.to_s.length}d: %s"
177
- end
167
+ line_number_fmt = Color.colorize("%#{end_pos.to_s.length}d", [:BLUE, :BOLD])
168
+ fmt = " %2s #{line_number_fmt}: %s"
169
+
178
170
  body = (start_pos..end_pos).map do |current_pos|
179
171
  sprintf(fmt, pos == current_pos ? '=>' : '', current_pos + 1, lines[current_pos])
180
172
  end.join("")
181
- "\nFrom: #{file} @ line #{pos + 1} :\n\n#{body}#{Color.clear if use_colorize}\n"
173
+
174
+ "\nFrom: #{file} @ line #{pos + 1} :\n\n#{body}#{Color.clear}\n"
182
175
  end
183
176
 
184
177
  def IRB.delete_caller