irb 1.3.8.pre.9 → 1.4.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc37bc2cdd7bf77d09704fb22c31aec464fc7aa391f2bc6a6619d8549bd0cd5d
4
- data.tar.gz: 20b8157c7167ccf5b30fef3d4b8340c3d1a316a59c742c968d0e62e0bd5010d7
3
+ metadata.gz: be0bdb184f8483785b83b91bc57339e994a15b2d1435720e8f17b9f04b2b924e
4
+ data.tar.gz: 02ca5b9f06cedc077c79f07ad33765225736f9d7ffa9bb93671cf739131a2d9c
5
5
  SHA512:
6
- metadata.gz: 9783aa13399d0eddb2e67cf3aa51760cfde1cc76f7b59d78158e83746359511e46824034d29f07181ffc91a51901bb6202562b8eab950649c0082f58295809d0
7
- data.tar.gz: f2a27869c90d81a93497515c38da52c0e19c113a308c95c264b863fb8edc9e1f96f558343bbe4bfe47b6a527ce4eaa98757380b700626d9f445f12b994b296d2
6
+ metadata.gz: faa52653f45b98a0ce82b215110376e3cac3faefa34928a50067e101c3171a0fbc492ba3b7a23334ac81f23448526e6931fca45925a07ab914aa2634c8e1de9a
7
+ data.tar.gz: 4da73a1293f021bcb3a0ed996ac4f48f3c73884d34efa438987b230cda72ce3aa0c6ac67865e57655cdcc8ffd49cb6ca267c564711345247ed889857f60156c1
data/Gemfile CHANGED
@@ -5,8 +5,8 @@ gemspec
5
5
  group :development do
6
6
  is_unix = RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
7
7
  is_truffleruby = RUBY_DESCRIPTION =~ /truffleruby/
8
- gem 'vterm', '>= 0.0.5' if is_unix && ENV['WITH_VTERM']
9
- gem 'yamatanooroti', '>= 0.0.6'
8
+ gem "vterm", ">= 0.0.5" if is_unix && ENV['WITH_VTERM']
9
+ gem "yamatanooroti", ">= 0.0.6"
10
10
  gem "rake"
11
11
  gem "stackprof" if is_unix && !is_truffleruby
12
12
  gem "test-unit"
data/doc/irb/irb.rd.ja CHANGED
@@ -51,6 +51,12 @@ irbの使い方は, Rubyさえ知っていればいたって簡単です. 基本
51
51
  オブジェクトの作成方法を 0 から 3 のいずれかに設定する.
52
52
  --echo 実行結果を表示する(デフォルト).
53
53
  --noecho 実行結果を表示しない.
54
+ --echo-on-assignment
55
+ 代入時に実行結果を表示する.
56
+ --noecho-on-assignment
57
+ 代入時に実行結果を表示しない.
58
+ --truncate-echo-on-assignment
59
+ 代入時に省略された実行結果を表示する(デフォルト).
54
60
  --inspect 結果出力にinspectを用いる.
55
61
  --noinspect 結果出力にinspectを用いない.
56
62
  --singleline シングルラインエディタを利用する.
data/irb.gemspec CHANGED
@@ -36,5 +36,5 @@ Gem::Specification.new do |spec|
36
36
 
37
37
  spec.required_ruby_version = Gem::Requirement.new(">= 2.5")
38
38
 
39
- spec.add_dependency "reline", ">= 0.2.8.pre.9"
39
+ spec.add_dependency "reline", ">= 0.3.0"
40
40
  end
data/lib/irb/cmd/info.rb CHANGED
@@ -16,8 +16,9 @@ module IRB
16
16
  str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
17
17
  str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty?
18
18
  str += "LC_ALL env: #{ENV["LC_ALL"]}\n" if ENV["LC_ALL"] && !ENV["LC_ALL"].empty?
19
+ str += "East Asian Ambiguous Width: #{Reline.ambiguous_width.inspect}\n"
19
20
  if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
20
- codepage = `chcp`.sub(/.*: (\d+)\n/, '\1')
21
+ codepage = `chcp`.b.sub(/.*: (\d+)\n/, '\1')
21
22
  str += "Code page: #{codepage}\n"
22
23
  end
23
24
  str
@@ -61,15 +61,12 @@ module IRB
61
61
  lex = RubyLex.new
62
62
  lines = File.read(file).lines[(first_line - 1)..-1]
63
63
  tokens = RubyLex.ripper_lex_without_warning(lines.join)
64
-
65
- code = +""
66
64
  prev_tokens = []
67
65
 
68
66
  # chunk with line number
69
- tokens.chunk { |tok| tok[0][0] }.each do |lnum, chunk|
70
- code << lines[lnum]
67
+ tokens.chunk { |tok| tok.pos[0] }.each do |lnum, chunk|
68
+ code = lines[0..lnum].join
71
69
  prev_tokens.concat chunk
72
-
73
70
  continue = lex.process_continue(prev_tokens)
74
71
  code_block_open = lex.check_code_block(code, prev_tokens)
75
72
  if !continue && !code_block_open
@@ -59,23 +59,27 @@ module IRB
59
59
  File.join(s.full_gem_path, p)
60
60
  end
61
61
  }
62
- }.flatten
63
- (gem_paths + $LOAD_PATH).uniq.sort
62
+ }.flatten if defined?(Gem::Specification)
63
+ (gem_paths.to_a | $LOAD_PATH).sort
64
64
  end
65
65
 
66
66
  def self.retrieve_files_to_require_from_load_path
67
- @@files_from_load_path ||= retrieve_gem_and_system_load_path.map { |path|
68
- begin
69
- Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: path)
70
- rescue Errno::ENOENT
71
- []
72
- end
73
- }.inject([]) { |result, names|
74
- shortest, *rest = names.map{ |n| n.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '') }.sort
75
- result.unshift(shortest) if shortest
76
- result.concat(rest)
77
- result
78
- }.uniq
67
+ @@files_from_load_path ||=
68
+ (
69
+ shortest = []
70
+ rest = retrieve_gem_and_system_load_path.each_with_object([]) { |path, result|
71
+ begin
72
+ names = Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: path)
73
+ rescue Errno::ENOENT
74
+ nil
75
+ end
76
+ next if names.empty?
77
+ names.map! { |n| n.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '') }.sort!
78
+ shortest << names.shift
79
+ result.concat(names)
80
+ }
81
+ shortest.sort! | rest
82
+ )
79
83
  end
80
84
 
81
85
  def self.retrieve_files_to_require_relative_from_current_dir
@@ -188,12 +192,12 @@ module IRB
188
192
  sym = $1
189
193
  candidates = Symbol.all_symbols.collect do |s|
190
194
  ":" + s.id2name.encode(Encoding.default_external)
191
- rescue Encoding::UndefinedConversionError
195
+ rescue EncodingError
192
196
  # ignore
193
197
  end
194
198
  candidates.grep(/^#{Regexp.quote(sym)}/)
195
199
 
196
- when /^::([A-Z][^:\.\(]*)$/
200
+ when /^::([A-Z][^:\.\(\)]*)$/
197
201
  # Absolute Constant or class methods
198
202
  receiver = $1
199
203
  candidates = Object.constants.collect{|m| m.to_s}
@@ -286,7 +290,7 @@ module IRB
286
290
  all_gvars.grep(Regexp.new(Regexp.quote(gvar)))
287
291
  end
288
292
 
289
- when /^([^."].*)(\.|::)([^.]*)$/
293
+ when /^([^.:"].*)(\.|::)([^.]*)$/
290
294
  # variable.func or func.func
291
295
  receiver = $1
292
296
  sep = $2
data/lib/irb/context.rb CHANGED
@@ -125,6 +125,8 @@ module IRB
125
125
  end
126
126
  self.save_history = IRB.conf[:SAVE_HISTORY] if IRB.conf[:SAVE_HISTORY]
127
127
 
128
+ @extra_doc_dirs = IRB.conf[:EXTRA_DOC_DIRS]
129
+
128
130
  @echo = IRB.conf[:ECHO]
129
131
  if @echo.nil?
130
132
  @echo = true
@@ -148,18 +150,18 @@ module IRB
148
150
 
149
151
  # The toplevel workspace, see #home_workspace
150
152
  attr_reader :workspace_home
151
- # WorkSpace in the current context
153
+ # WorkSpace in the current context.
152
154
  attr_accessor :workspace
153
- # The current thread in this context
155
+ # The current thread in this context.
154
156
  attr_reader :thread
155
- # The current input method
157
+ # The current input method.
156
158
  #
157
159
  # Can be either StdioInputMethod, ReadlineInputMethod,
158
160
  # ReidlineInputMethod, FileInputMethod or other specified when the
159
161
  # context is created. See ::new for more # information on +input_method+.
160
162
  attr_accessor :io
161
163
 
162
- # Current irb session
164
+ # Current irb session.
163
165
  attr_accessor :irb
164
166
  # A copy of the default <code>IRB.conf[:AP_NAME]</code>
165
167
  attr_accessor :ap_name
@@ -193,15 +195,15 @@ module IRB
193
195
 
194
196
  # A copy of the default <code>IRB.conf[:PROMPT_MODE]</code>
195
197
  attr_reader :prompt_mode
196
- # Standard IRB prompt
198
+ # Standard IRB prompt.
197
199
  #
198
200
  # See IRB@Customizing+the+IRB+Prompt for more information.
199
201
  attr_accessor :prompt_i
200
- # IRB prompt for continuated strings
202
+ # IRB prompt for continuated strings.
201
203
  #
202
204
  # See IRB@Customizing+the+IRB+Prompt for more information.
203
205
  attr_accessor :prompt_s
204
- # IRB prompt for continuated statement (e.g. immediately after an +if+)
206
+ # IRB prompt for continuated statement. (e.g. immediately after an +if+)
205
207
  #
206
208
  # See IRB@Customizing+the+IRB+Prompt for more information.
207
209
  attr_accessor :prompt_c
@@ -241,6 +243,9 @@ module IRB
241
243
  #
242
244
  # If set to +false+, <code>^D</code> will quit irb.
243
245
  attr_accessor :ignore_eof
246
+ # Specify the installation locations of the ri file to be displayed in the
247
+ # document dialog.
248
+ attr_accessor :extra_doc_dirs
244
249
  # Whether to echo the return value to output or not.
245
250
  #
246
251
  # Uses <code>IRB.conf[:ECHO]</code> if available, or defaults to +true+.
@@ -252,7 +257,7 @@ module IRB
252
257
  # puts "omg"
253
258
  # # omg
254
259
  attr_accessor :echo
255
- # Whether to echo for assignment expressions
260
+ # Whether to echo for assignment expressions.
256
261
  #
257
262
  # If set to +false+, the value of assignment will not be shown.
258
263
  #
@@ -264,13 +269,28 @@ module IRB
264
269
  #
265
270
  # a = "omg"
266
271
  # #=> omg
272
+ #
267
273
  # a = "omg" * 10
268
274
  # #=> omgomgomgomgomgomgomg...
275
+ #
269
276
  # IRB.CurrentContext.echo_on_assignment = false
270
277
  # a = "omg"
278
+ #
271
279
  # IRB.CurrentContext.echo_on_assignment = true
272
- # a = "omg"
280
+ # a = "omg" * 10
273
281
  # #=> omgomgomgomgomgomgomgomgomgomg
282
+ #
283
+ # To set the behaviour of showing on assignment in irb:
284
+ #
285
+ # IRB.conf[:ECHO_ON_ASSIGNMENT] = :truncate or true or false
286
+ #
287
+ # or
288
+ #
289
+ # irb_context.echo_on_assignment = :truncate or true or false
290
+ #
291
+ # or
292
+ #
293
+ # IRB.CurrentContext.echo_on_assignment = :truncate or true or false
274
294
  attr_accessor :echo_on_assignment
275
295
  # Whether a newline is put before multiline output.
276
296
  #
@@ -371,6 +391,7 @@ module IRB
371
391
  @prompt_c = pconf[:PROMPT_C]
372
392
  @prompt_n = pconf[:PROMPT_N]
373
393
  @return_format = pconf[:RETURN]
394
+ @return_format = "%s\n" if @return_format == nil
374
395
  if ai = pconf.include?(:AUTO_INDENT)
375
396
  @auto_indent_mode = ai
376
397
  else
@@ -463,6 +484,8 @@ module IRB
463
484
  # Exits the current session, see IRB.irb_exit
464
485
  def exit(ret = 0)
465
486
  IRB.irb_exit(@irb, ret)
487
+ rescue UncaughtThrowError
488
+ super
466
489
  end
467
490
 
468
491
  NOPRINTING_IVARS = ["@last_value"] # :nodoc:
data/lib/irb/init.rb CHANGED
@@ -51,6 +51,7 @@ module IRB # :nodoc:
51
51
  @CONF[:USE_LOADER] = false
52
52
  @CONF[:IGNORE_SIGINT] = true
53
53
  @CONF[:IGNORE_EOF] = false
54
+ @CONF[:EXTRA_DOC_DIRS] = []
54
55
  @CONF[:ECHO] = nil
55
56
  @CONF[:ECHO_ON_ASSIGNMENT] = nil
56
57
  @CONF[:VERBOSE] = nil
@@ -257,6 +258,9 @@ module IRB # :nodoc:
257
258
  @CONF[:USE_MULTILINE] = true
258
259
  when "--nomultiline", "--noreidline"
259
260
  @CONF[:USE_MULTILINE] = false
261
+ when /^--extra-doc-dir(?:=(.+))?/
262
+ opt = $1 || argv.shift
263
+ @CONF[:EXTRA_DOC_DIRS] << opt
260
264
  when "--echo"
261
265
  @CONF[:ECHO] = true
262
266
  when "--noecho"
@@ -265,7 +265,8 @@ module IRB
265
265
 
266
266
  class ReidlineInputMethod < InputMethod
267
267
  include Reline
268
- # Creates a new input method object using Readline
268
+
269
+ # Creates a new input method object using Reline
269
270
  def initialize
270
271
  IRB.__send__(:set_encoding, Reline.encoding_system_needs.name, override: false)
271
272
  super
@@ -317,13 +318,10 @@ module IRB
317
318
  dialog.trap_key = nil
318
319
  alt_d = [
319
320
  [Reline::Key.new(nil, 0xE4, true)], # Normal Alt+d.
320
- [195, 164] # The "ä" that appears when Alt+d is pressed on xterm.
321
+ [27, 100], # Normal Alt+d when convert-meta isn't used.
322
+ [195, 164], # The "ä" that appears when Alt+d is pressed on xterm.
323
+ [226, 136, 130] # The "∂" that appears when Alt+d in pressed on iTerm2.
321
324
  ]
322
- begin
323
- require 'rdoc'
324
- rescue LoadError
325
- return nil
326
- end
327
325
 
328
326
  if just_cursor_moving and completion_journey_data.nil?
329
327
  return nil
@@ -333,7 +331,9 @@ module IRB
333
331
  name = result[pointer]
334
332
  name = IRB::InputCompletor.retrieve_completion_data(name, doc_namespace: true)
335
333
 
336
- driver = RDoc::RI::Driver.new
334
+ options = {}
335
+ options[:extra_doc_dirs] = IRB.conf[:EXTRA_DOC_DIRS] unless IRB.conf[:EXTRA_DOC_DIRS].empty?
336
+ driver = RDoc::RI::Driver.new(options)
337
337
 
338
338
  if key.match?(dialog.name)
339
339
  begin
@@ -370,14 +370,39 @@ module IRB
370
370
  end
371
371
  return nil if doc.nil?
372
372
  width = 40
373
+
374
+ right_x = cursor_pos_to_render.x + autocomplete_dialog.width
375
+ if right_x + width > screen_width
376
+ right_width = screen_width - (right_x + 1)
377
+ left_x = autocomplete_dialog.column - width
378
+ left_x = 0 if left_x < 0
379
+ left_width = width > autocomplete_dialog.column ? autocomplete_dialog.column : width
380
+ if right_width.positive? and left_width.positive?
381
+ if right_width >= left_width
382
+ width = right_width
383
+ x = right_x
384
+ else
385
+ width = left_width
386
+ x = left_x
387
+ end
388
+ elsif right_width.positive? and left_width <= 0
389
+ width = right_width
390
+ x = right_x
391
+ elsif right_width <= 0 and left_width.positive?
392
+ width = left_width
393
+ x = left_x
394
+ else # Both are negative width.
395
+ return nil
396
+ end
397
+ else
398
+ x = right_x
399
+ end
373
400
  formatter = RDoc::Markup::ToAnsi.new
374
401
  formatter.width = width
375
402
  dialog.trap_key = alt_d
376
403
  message = 'Press Alt+d to read the full document'
377
404
  contents = [message] + doc.accept(formatter).split("\n")
378
405
 
379
- x = cursor_pos_to_render.x + autocomplete_dialog.width
380
- x = autocomplete_dialog.column - width if x + width >= screen_width
381
406
  y = cursor_pos_to_render.y
382
407
  DialogRenderInfo.new(pos: Reline::CursorPos.new(x, y), contents: contents, width: width, bg_color: '49')
383
408
  }
@@ -20,8 +20,15 @@ Usage: irb.rb [options] [programfile] [arguments]
20
20
  -W[level=2] Same as `ruby -W`
21
21
  --context-mode n Set n[0-4] to method to create Binding Object,
22
22
  when new workspace was created
23
- --echo Show result(default)
23
+ --extra-doc-dir Add an extra doc dir for the doc dialog
24
+ --echo Show result (default)
24
25
  --noecho Don't show result
26
+ --echo-on-assignment
27
+ Show result on assignment
28
+ --noecho-on-assignment
29
+ Don't show result on assignment
30
+ --truncate-echo-on-assignment
31
+ Show truncated result on assignment (default)
25
32
  --inspect Use `inspect' for output
26
33
  --noinspect Don't use inspect for output
27
34
  --multiline Use multiline editor module
data/lib/irb/ruby-lex.rb CHANGED
@@ -87,8 +87,8 @@ class RubyLex
87
87
  tokens.each do |t|
88
88
  partial_tokens << t
89
89
  unprocessed_tokens << t
90
- if t[2].include?("\n")
91
- t_str = t[2]
90
+ if t.tok.include?("\n")
91
+ t_str = t.tok
92
92
  t_str.each_line("\n") do |s|
93
93
  code << s << "\n"
94
94
  ltype, indent, continue, code_block_open = check_state(code, partial_tokens, context: context)
@@ -97,9 +97,10 @@ class RubyLex
97
97
  end
98
98
  unprocessed_tokens = []
99
99
  else
100
- code << t[2]
100
+ code << t.tok
101
101
  end
102
102
  end
103
+
103
104
  unless unprocessed_tokens.empty?
104
105
  ltype, indent, continue, code_block_open = check_state(code, unprocessed_tokens, context: context)
105
106
  result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
@@ -107,6 +108,7 @@ class RubyLex
107
108
  result
108
109
  end
109
110
  end
111
+
110
112
  if p.respond_to?(:call)
111
113
  @input = p
112
114
  elsif block_given?
@@ -153,19 +155,19 @@ class RubyLex
153
155
  pos_to_index = {}
154
156
  lexer.scan.each do |t|
155
157
  next if t.pos.first == 0
156
- if pos_to_index.has_key?(t[0])
157
- index = pos_to_index[t[0]]
158
+ if pos_to_index.has_key?(t.pos)
159
+ index = pos_to_index[t.pos]
158
160
  found_tk = tokens[index]
159
- if ERROR_TOKENS.include?(found_tk[1]) && !ERROR_TOKENS.include?(t[1])
161
+ if ERROR_TOKENS.include?(found_tk.event) && !ERROR_TOKENS.include?(t.event)
160
162
  tokens[index] = t
161
163
  end
162
164
  else
163
- pos_to_index[t[0]] = tokens.size
165
+ pos_to_index[t.pos] = tokens.size
164
166
  tokens << t
165
167
  end
166
168
  end
167
169
  else
168
- tokens = lexer.parse
170
+ tokens = lexer.parse.reject { |it| it.pos.first == 0 }
169
171
  end
170
172
  end
171
173
  tokens
@@ -175,17 +177,17 @@ class RubyLex
175
177
 
176
178
  def find_prev_spaces(line_index)
177
179
  return 0 if @tokens.size == 0
178
- md = @tokens[0][2].match(/(\A +)/)
180
+ md = @tokens[0].tok.match(/(\A +)/)
179
181
  prev_spaces = md.nil? ? 0 : md[1].count(' ')
180
182
  line_count = 0
181
183
  @tokens.each_with_index do |t, i|
182
- if t[2].include?("\n")
183
- line_count += t[2].count("\n")
184
+ if t.tok.include?("\n")
185
+ line_count += t.tok.count("\n")
184
186
  if line_count >= line_index
185
187
  return prev_spaces
186
188
  end
187
189
  if (@tokens.size - 1) > i
188
- md = @tokens[i + 1][2].match(/(\A +)/)
190
+ md = @tokens[i + 1].tok.match(/(\A +)/)
189
191
  prev_spaces = md.nil? ? 0 : md[1].count(' ')
190
192
  end
191
193
  end
@@ -207,7 +209,7 @@ class RubyLex
207
209
  last_line = lines[line_index]&.byteslice(0, byte_pointer)
208
210
  code += last_line if last_line
209
211
  @tokens = self.class.ripper_lex_without_warning(code, context: context)
210
- corresponding_token_depth = check_corresponding_token_depth
212
+ corresponding_token_depth = check_corresponding_token_depth(lines, line_index)
211
213
  if corresponding_token_depth
212
214
  corresponding_token_depth
213
215
  else
@@ -295,18 +297,18 @@ class RubyLex
295
297
 
296
298
  def process_continue(tokens = @tokens)
297
299
  # last token is always newline
298
- if tokens.size >= 2 and tokens[-2][1] == :on_regexp_end
300
+ if tokens.size >= 2 and tokens[-2].event == :on_regexp_end
299
301
  # end of regexp literal
300
302
  return false
301
- elsif tokens.size >= 2 and tokens[-2][1] == :on_semicolon
303
+ elsif tokens.size >= 2 and tokens[-2].event == :on_semicolon
302
304
  return false
303
- elsif tokens.size >= 2 and tokens[-2][1] == :on_kw and ['begin', 'else', 'ensure'].include?(tokens[-2][2])
305
+ elsif tokens.size >= 2 and tokens[-2].event == :on_kw and ['begin', 'else', 'ensure'].include?(tokens[-2].tok)
304
306
  return false
305
- elsif !tokens.empty? and tokens.last[2] == "\\\n"
307
+ elsif !tokens.empty? and tokens.last.tok == "\\\n"
306
308
  return true
307
- elsif tokens.size >= 1 and tokens[-1][1] == :on_heredoc_end # "EOH\n"
309
+ elsif tokens.size >= 1 and tokens[-1].event == :on_heredoc_end # "EOH\n"
308
310
  return false
309
- 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/
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/
310
312
  # end of literal except for regexp
311
313
  # endless range at end of line is not a continue
312
314
  return true
@@ -316,7 +318,7 @@ class RubyLex
316
318
 
317
319
  def check_code_block(code, tokens = @tokens)
318
320
  return true if tokens.empty?
319
- if tokens.last[1] == :on_heredoc_beg
321
+ if tokens.last.event == :on_heredoc_beg
320
322
  return true
321
323
  end
322
324
 
@@ -388,7 +390,7 @@ class RubyLex
388
390
  end
389
391
 
390
392
  if defined?(Ripper::EXPR_BEG)
391
- last_lex_state = tokens.last[3]
393
+ last_lex_state = tokens.last.state
392
394
  if last_lex_state.allbits?(Ripper::EXPR_BEG)
393
395
  return false
394
396
  elsif last_lex_state.allbits?(Ripper::EXPR_DOT)
@@ -413,14 +415,14 @@ class RubyLex
413
415
  tokens.each_with_index { |t, index|
414
416
  # detecting one-liner method definition
415
417
  if in_oneliner_def.nil?
416
- if t[3].allbits?(Ripper::EXPR_ENDFN)
418
+ if t.state.allbits?(Ripper::EXPR_ENDFN)
417
419
  in_oneliner_def = :ENDFN
418
420
  end
419
421
  else
420
- if t[3].allbits?(Ripper::EXPR_ENDFN)
422
+ if t.state.allbits?(Ripper::EXPR_ENDFN)
421
423
  # continuing
422
- elsif t[3].allbits?(Ripper::EXPR_BEG)
423
- if t[2] == '='
424
+ elsif t.state.allbits?(Ripper::EXPR_BEG)
425
+ if t.tok == '='
424
426
  in_oneliner_def = :BODY
425
427
  end
426
428
  else
@@ -432,14 +434,14 @@ class RubyLex
432
434
  end
433
435
  end
434
436
 
435
- case t[1]
437
+ case t.event
436
438
  when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
437
439
  indent += 1
438
440
  when :on_rbracket, :on_rbrace, :on_rparen
439
441
  indent -= 1
440
442
  when :on_kw
441
- next if index > 0 and tokens[index - 1][3].allbits?(Ripper::EXPR_FNAME)
442
- case t[2]
443
+ next if index > 0 and tokens[index - 1].state.allbits?(Ripper::EXPR_FNAME)
444
+ case t.tok
443
445
  when 'do'
444
446
  syntax_of_do = take_corresponding_syntax_to_kw_do(tokens, index)
445
447
  indent += 1 if syntax_of_do == :method_calling
@@ -447,7 +449,7 @@ class RubyLex
447
449
  indent += 1
448
450
  when 'if', 'unless', 'while', 'until'
449
451
  # postfix if/unless/while/until must be Ripper::EXPR_LABEL
450
- indent += 1 unless t[3].allbits?(Ripper::EXPR_LABEL)
452
+ indent += 1 unless t.state.allbits?(Ripper::EXPR_LABEL)
451
453
  when 'end'
452
454
  indent -= 1
453
455
  end
@@ -459,14 +461,14 @@ class RubyLex
459
461
 
460
462
  def is_method_calling?(tokens, index)
461
463
  tk = tokens[index]
462
- if tk[3].anybits?(Ripper::EXPR_CMDARG) and tk[1] == :on_ident
464
+ if tk.state.anybits?(Ripper::EXPR_CMDARG) and tk.event == :on_ident
463
465
  # The target method call to pass the block with "do".
464
466
  return true
465
- elsif tk[3].anybits?(Ripper::EXPR_ARG) and tk[1] == :on_ident
466
- non_sp_index = tokens[0..(index - 1)].rindex{ |t| t[1] != :on_sp }
467
+ elsif tk.state.anybits?(Ripper::EXPR_ARG) and tk.event == :on_ident
468
+ non_sp_index = tokens[0..(index - 1)].rindex{ |t| t.event != :on_sp }
467
469
  if non_sp_index
468
470
  prev_tk = tokens[non_sp_index]
469
- if prev_tk[3].anybits?(Ripper::EXPR_DOT) and prev_tk[1] == :on_period
471
+ if prev_tk.state.anybits?(Ripper::EXPR_DOT) and prev_tk.event == :on_period
470
472
  # The target method call with receiver to pass the block with "do".
471
473
  return true
472
474
  end
@@ -477,21 +479,21 @@ class RubyLex
477
479
 
478
480
  def take_corresponding_syntax_to_kw_do(tokens, index)
479
481
  syntax_of_do = nil
480
- # Finding a syntax correnponding to "do".
482
+ # Finding a syntax corresponding to "do".
481
483
  index.downto(0) do |i|
482
484
  tk = tokens[i]
483
485
  # In "continue", the token isn't the corresponding syntax to "do".
484
- non_sp_index = tokens[0..(i - 1)].rindex{ |t| t[1] != :on_sp }
486
+ non_sp_index = tokens[0..(i - 1)].rindex{ |t| t.event != :on_sp }
485
487
  first_in_fomula = false
486
488
  if non_sp_index.nil?
487
489
  first_in_fomula = true
488
- elsif [:on_ignored_nl, :on_nl, :on_comment].include?(tokens[non_sp_index][1])
490
+ elsif [:on_ignored_nl, :on_nl, :on_comment].include?(tokens[non_sp_index].event)
489
491
  first_in_fomula = true
490
492
  end
491
493
  if is_method_calling?(tokens, i)
492
494
  syntax_of_do = :method_calling
493
495
  break if first_in_fomula
494
- elsif tk[1] == :on_kw && %w{while until for}.include?(tk[2])
496
+ elsif tk.event == :on_kw && %w{while until for}.include?(tk.tok)
495
497
  # A loop syntax in front of "do" found.
496
498
  #
497
499
  # while cond do # also "until" or "for"
@@ -508,18 +510,18 @@ class RubyLex
508
510
 
509
511
  def is_the_in_correspond_to_a_for(tokens, index)
510
512
  syntax_of_in = nil
511
- # Finding a syntax correnponding to "do".
513
+ # Finding a syntax corresponding to "do".
512
514
  index.downto(0) do |i|
513
515
  tk = tokens[i]
514
516
  # In "continue", the token isn't the corresponding syntax to "do".
515
- non_sp_index = tokens[0..(i - 1)].rindex{ |t| t[1] != :on_sp }
517
+ non_sp_index = tokens[0..(i - 1)].rindex{ |t| t.event != :on_sp }
516
518
  first_in_fomula = false
517
519
  if non_sp_index.nil?
518
520
  first_in_fomula = true
519
- elsif [:on_ignored_nl, :on_nl, :on_comment].include?(tokens[non_sp_index][1])
521
+ elsif [:on_ignored_nl, :on_nl, :on_comment].include?(tokens[non_sp_index].event)
520
522
  first_in_fomula = true
521
523
  end
522
- if tk[1] == :on_kw && tk[2] == 'for'
524
+ if tk.event == :on_kw && tk.tok == 'for'
523
525
  # A loop syntax in front of "do" found.
524
526
  #
525
527
  # while cond do # also "until" or "for"
@@ -541,14 +543,14 @@ class RubyLex
541
543
  @tokens.each_with_index do |t, index|
542
544
  # detecting one-liner method definition
543
545
  if in_oneliner_def.nil?
544
- if t[3].allbits?(Ripper::EXPR_ENDFN)
546
+ if t.state.allbits?(Ripper::EXPR_ENDFN)
545
547
  in_oneliner_def = :ENDFN
546
548
  end
547
549
  else
548
- if t[3].allbits?(Ripper::EXPR_ENDFN)
550
+ if t.state.allbits?(Ripper::EXPR_ENDFN)
549
551
  # continuing
550
- elsif t[3].allbits?(Ripper::EXPR_BEG)
551
- if t[2] == '='
552
+ elsif t.state.allbits?(Ripper::EXPR_BEG)
553
+ if t.tok == '='
552
554
  in_oneliner_def = :BODY
553
555
  end
554
556
  else
@@ -560,7 +562,7 @@ class RubyLex
560
562
  end
561
563
  end
562
564
 
563
- case t[1]
565
+ case t.event
564
566
  when :on_ignored_nl, :on_nl, :on_comment
565
567
  if index != (@tokens.size - 1) and in_oneliner_def != :BODY
566
568
  depth_difference = 0
@@ -570,15 +572,16 @@ class RubyLex
570
572
  when :on_sp
571
573
  next
572
574
  end
573
- case t[1]
575
+
576
+ case t.event
574
577
  when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
575
578
  depth_difference += 1
576
579
  open_brace_on_line += 1
577
580
  when :on_rbracket, :on_rbrace, :on_rparen
578
581
  depth_difference -= 1 if open_brace_on_line > 0
579
582
  when :on_kw
580
- next if index > 0 and @tokens[index - 1][3].allbits?(Ripper::EXPR_FNAME)
581
- case t[2]
583
+ next if index > 0 and @tokens[index - 1].state.allbits?(Ripper::EXPR_FNAME)
584
+ case t.tok
582
585
  when 'do'
583
586
  syntax_of_do = take_corresponding_syntax_to_kw_do(@tokens, index)
584
587
  depth_difference += 1 if syntax_of_do == :method_calling
@@ -586,7 +589,7 @@ class RubyLex
586
589
  depth_difference += 1
587
590
  when 'if', 'unless', 'while', 'until', 'rescue'
588
591
  # postfix if/unless/while/until/rescue must be Ripper::EXPR_LABEL
589
- unless t[3].allbits?(Ripper::EXPR_LABEL)
592
+ unless t.state.allbits?(Ripper::EXPR_LABEL)
590
593
  depth_difference += 1
591
594
  end
592
595
  when 'else', 'elsif', 'ensure', 'when'
@@ -603,7 +606,7 @@ class RubyLex
603
606
  depth_difference
604
607
  end
605
608
 
606
- def check_corresponding_token_depth
609
+ def check_corresponding_token_depth(lines, line_index)
607
610
  corresponding_token_depth = nil
608
611
  is_first_spaces_of_line = true
609
612
  is_first_printable_of_line = true
@@ -611,17 +614,22 @@ class RubyLex
611
614
  spaces_at_line_head = 0
612
615
  open_brace_on_line = 0
613
616
  in_oneliner_def = nil
617
+
618
+ if heredoc_scope?
619
+ return lines[line_index][/^ */].length
620
+ end
621
+
614
622
  @tokens.each_with_index do |t, index|
615
623
  # detecting one-liner method definition
616
624
  if in_oneliner_def.nil?
617
- if t[3].allbits?(Ripper::EXPR_ENDFN)
625
+ if t.state.allbits?(Ripper::EXPR_ENDFN)
618
626
  in_oneliner_def = :ENDFN
619
627
  end
620
628
  else
621
- if t[3].allbits?(Ripper::EXPR_ENDFN)
629
+ if t.state.allbits?(Ripper::EXPR_ENDFN)
622
630
  # continuing
623
- elsif t[3].allbits?(Ripper::EXPR_BEG)
624
- if t[2] == '='
631
+ elsif t.state.allbits?(Ripper::EXPR_BEG)
632
+ if t.tok == '='
625
633
  in_oneliner_def = :BODY
626
634
  end
627
635
  else
@@ -638,7 +646,7 @@ class RubyLex
638
646
  end
639
647
  end
640
648
 
641
- case t[1]
649
+ case t.event
642
650
  when :on_ignored_nl, :on_nl, :on_comment
643
651
  if in_oneliner_def != :BODY
644
652
  corresponding_token_depth = nil
@@ -649,11 +657,12 @@ class RubyLex
649
657
  end
650
658
  next
651
659
  when :on_sp
652
- spaces_at_line_head = t[2].count(' ') if is_first_spaces_of_line
660
+ spaces_at_line_head = t.tok.count(' ') if is_first_spaces_of_line
653
661
  is_first_spaces_of_line = false
654
662
  next
655
663
  end
656
- case t[1]
664
+
665
+ case t.event
657
666
  when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
658
667
  spaces_of_nest.push(spaces_at_line_head + open_brace_on_line * 2)
659
668
  open_brace_on_line += 1
@@ -666,8 +675,8 @@ class RubyLex
666
675
  end
667
676
  open_brace_on_line -= 1
668
677
  when :on_kw
669
- next if index > 0 and @tokens[index - 1][3].allbits?(Ripper::EXPR_FNAME)
670
- case t[2]
678
+ next if index > 0 and @tokens[index - 1].state.allbits?(Ripper::EXPR_FNAME)
679
+ case t.tok
671
680
  when 'do'
672
681
  syntax_of_do = take_corresponding_syntax_to_kw_do(@tokens, index)
673
682
  if syntax_of_do == :method_calling
@@ -676,16 +685,20 @@ class RubyLex
676
685
  when 'def', 'case', 'for', 'begin', 'class', 'module'
677
686
  spaces_of_nest.push(spaces_at_line_head)
678
687
  when 'rescue'
679
- unless t[3].allbits?(Ripper::EXPR_LABEL)
688
+ unless t.state.allbits?(Ripper::EXPR_LABEL)
680
689
  corresponding_token_depth = spaces_of_nest.last
681
690
  end
682
691
  when 'if', 'unless', 'while', 'until'
683
692
  # postfix if/unless/while/until must be Ripper::EXPR_LABEL
684
- unless t[3].allbits?(Ripper::EXPR_LABEL)
693
+ unless t.state.allbits?(Ripper::EXPR_LABEL)
685
694
  spaces_of_nest.push(spaces_at_line_head)
686
695
  end
687
- when 'else', 'elsif', 'ensure', 'when', 'in'
696
+ when 'else', 'elsif', 'ensure', 'when'
688
697
  corresponding_token_depth = spaces_of_nest.last
698
+ when 'in'
699
+ if in_keyword_case_scope?
700
+ corresponding_token_depth = spaces_of_nest.last
701
+ end
689
702
  when 'end'
690
703
  if is_first_printable_of_line
691
704
  corresponding_token_depth = spaces_of_nest.pop
@@ -707,7 +720,7 @@ class RubyLex
707
720
  end_type = []
708
721
  while i < tokens.size
709
722
  t = tokens[i]
710
- case t[1]
723
+ case t.event
711
724
  when *end_type.last
712
725
  start_token.pop
713
726
  end_type.pop
@@ -720,7 +733,7 @@ class RubyLex
720
733
  when :on_symbeg
721
734
  acceptable_single_tokens = %i{on_ident on_const on_op on_cvar on_ivar on_gvar on_kw on_int on_backtick}
722
735
  if (i + 1) < tokens.size
723
- if acceptable_single_tokens.all?{ |st| tokens[i + 1][1] != st }
736
+ if acceptable_single_tokens.all?{ |st| tokens[i + 1].event != st }
724
737
  start_token << t
725
738
  end_type << :on_tstring_end
726
739
  else
@@ -739,14 +752,16 @@ class RubyLex
739
752
  end
740
753
  i += 1
741
754
  end
742
- start_token.last.nil? ? '' : start_token.last
755
+ start_token.last.nil? ? nil : start_token.last
743
756
  end
744
757
 
745
758
  def process_literal_type(tokens = @tokens)
746
759
  start_token = check_string_literal(tokens)
747
- case start_token[1]
760
+ return nil if start_token == ""
761
+
762
+ case start_token&.event
748
763
  when :on_tstring_beg
749
- case start_token[2]
764
+ case start_token&.tok
750
765
  when ?" then ?"
751
766
  when /^%.$/ then ?"
752
767
  when /^%Q.$/ then ?"
@@ -761,7 +776,7 @@ class RubyLex
761
776
  when :on_qsymbols_beg then ?]
762
777
  when :on_symbols_beg then ?]
763
778
  when :on_heredoc_beg
764
- start_token[2] =~ /<<[-~]?(['"`])[_a-zA-Z0-9]+\1/
779
+ start_token&.tok =~ /<<[-~]?(['"`])[_a-zA-Z0-9]+\1/
765
780
  case $1
766
781
  when ?" then ?"
767
782
  when ?' then ?'
@@ -789,6 +804,7 @@ class RubyLex
789
804
  false
790
805
  end
791
806
  end
807
+
792
808
  if index
793
809
  first_token = nil
794
810
  last_line_tokens = tokens[(index + 1)..(tokens.size - 1)]
@@ -798,6 +814,7 @@ class RubyLex
798
814
  break
799
815
  end
800
816
  end
817
+
801
818
  if first_token.nil?
802
819
  return false
803
820
  elsif first_token && first_token.state == Ripper::EXPR_DOT
@@ -817,5 +834,28 @@ class RubyLex
817
834
  end
818
835
  false
819
836
  end
837
+
838
+ private
839
+
840
+ def heredoc_scope?
841
+ heredoc_tokens = @tokens.select { |t| [:on_heredoc_beg, :on_heredoc_end].include?(t.event) }
842
+ heredoc_tokens[-1]&.event == :on_heredoc_beg
843
+ end
844
+
845
+ def in_keyword_case_scope?
846
+ kw_tokens = @tokens.select { |t| t.event == :on_kw && ['case', 'for', 'end'].include?(t.tok) }
847
+ counter = 0
848
+ kw_tokens.reverse.each do |t|
849
+ if t.tok == 'case'
850
+ return true if counter.zero?
851
+ counter += 1
852
+ elsif t.tok == 'for'
853
+ counter += 1
854
+ elsif t.tok == 'end'
855
+ counter -= 1
856
+ end
857
+ end
858
+ false
859
+ end
820
860
  end
821
861
  # :startdoc:
data/lib/irb/version.rb CHANGED
@@ -11,7 +11,7 @@
11
11
  #
12
12
 
13
13
  module IRB # :nodoc:
14
- VERSION = "1.3.8.pre.9"
14
+ VERSION = "1.4.1"
15
15
  @RELEASE_VERSION = VERSION
16
- @LAST_UPDATE_DATE = "2021-09-10"
16
+ @LAST_UPDATE_DATE = "2021-12-25"
17
17
  end
data/lib/irb.rb CHANGED
@@ -62,8 +62,15 @@ require_relative "irb/easter-egg"
62
62
  # -W[level=2] Same as `ruby -W`
63
63
  # --context-mode n Set n[0-4] to method to create Binding Object,
64
64
  # when new workspace was created
65
- # --echo Show result(default)
65
+ # --extra-doc-dir Add an extra doc dir for the doc dialog
66
+ # --echo Show result (default)
66
67
  # --noecho Don't show result
68
+ # --echo-on-assignment
69
+ # Show result on assignment
70
+ # --noecho-on-assignment
71
+ # Don't show result on assignment
72
+ # --truncate-echo-on-assignment
73
+ # Show truncated result on assignment (default)
67
74
  # --inspect Use `inspect' for output
68
75
  # --noinspect Don't use inspect for output
69
76
  # --multiline Use multiline editor module
@@ -607,7 +614,7 @@ module IRB
607
614
  ret = conv.primitive_convert(str, dst)
608
615
  case ret
609
616
  when :invalid_byte_sequence
610
- conv.insert_output(conf.primitive_errinfo[3].dump[1..-2])
617
+ conv.insert_output(conv.primitive_errinfo[3].dump[1..-2])
611
618
  redo
612
619
  when :undefined_conversion
613
620
  c = conv.primitive_errinfo[3].dup.force_encoding(conv.primitive_errinfo[1])
@@ -817,17 +824,20 @@ module IRB
817
824
  diff_size = output_width - Reline::Unicode.calculate_width(first_line, true)
818
825
  if diff_size.positive? and output_width > winwidth
819
826
  lines, _ = Reline::Unicode.split_by_width(first_line, winwidth - diff_size - 3)
820
- str = "%s...\e[0m" % lines.first
827
+ str = "%s..." % lines.first
828
+ str += "\e[0m" if @context.use_colorize
821
829
  multiline_p = false
822
830
  else
823
831
  str = str.gsub(/(\A.*?\n).*/m, "\\1...")
832
+ str += "\e[0m" if @context.use_colorize
824
833
  end
825
834
  else
826
835
  output_width = Reline::Unicode.calculate_width(@context.return_format % str, true)
827
836
  diff_size = output_width - Reline::Unicode.calculate_width(str, true)
828
837
  if diff_size.positive? and output_width > winwidth
829
838
  lines, _ = Reline::Unicode.split_by_width(str, winwidth - diff_size - 3)
830
- str = "%s...\e[0m" % lines.first
839
+ str = "%s..." % lines.first
840
+ str += "\e[0m" if @context.use_colorize
831
841
  end
832
842
  end
833
843
  end
@@ -861,7 +871,7 @@ module IRB
861
871
 
862
872
  # If the expression is invalid, Ripper.sexp should return nil which will
863
873
  # result in false being returned. Any valid expression should return an
864
- # s-expression where the second selement of the top level array is an
874
+ # s-expression where the second element of the top level array is an
865
875
  # array of parsed expressions. The first element of each expression is the
866
876
  # expression's type.
867
877
  verbose, $VERBOSE = $VERBOSE, nil
data/man/irb.1 CHANGED
@@ -105,13 +105,27 @@ Uses singleline editor module.
105
105
  Doesn't use singleline editor module.
106
106
  .Pp
107
107
  .Pp
108
+ .It Fl -extra-doc-dir
109
+ Add an extra doc dir for the doc dialog.
110
+ .Pp
111
+ .Pp
108
112
  .It Fl -echo
109
- Show result(default).
113
+ Show result (default).
110
114
  .Pp
111
115
  .It Fl -noecho
112
116
  Don't show result.
113
117
  .Pp
114
118
  .Pp
119
+ .It Fl -echo-on-assignment
120
+ Show result on assignment.
121
+ .Pp
122
+ .It Fl -noecho-on-assignment
123
+ Don't show result on assignment.
124
+ .Pp
125
+ .It Fl -truncate-echo-on-assignment
126
+ Show truncated result on assignment (default).
127
+ .Pp
128
+ .Pp
115
129
  .It Fl -colorize
116
130
  Use colorization.
117
131
  .Pp
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: irb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.8.pre.9
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keiju ISHITSUKA
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-10 00:00:00.000000000 Z
11
+ date: 2021-12-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: reline
15
- prerelease: false
16
15
  requirement: !ruby/object:Gem::Requirement
17
16
  requirements:
18
17
  - - ">="
19
18
  - !ruby/object:Gem::Version
20
- version: 0.2.8.pre.9
19
+ version: 0.3.0
21
20
  type: :runtime
21
+ prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.8.pre.9
26
+ version: 0.3.0
27
27
  description: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).
28
28
  email:
29
29
  - keiju@ruby-lang.org
@@ -97,7 +97,7 @@ licenses:
97
97
  - Ruby
98
98
  - BSD-2-Clause
99
99
  metadata: {}
100
- post_install_message:
100
+ post_install_message:
101
101
  rdoc_options: []
102
102
  require_paths:
103
103
  - lib
@@ -108,12 +108,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
108
108
  version: '2.5'
109
109
  required_rubygems_version: !ruby/object:Gem::Requirement
110
110
  requirements:
111
- - - ">"
111
+ - - ">="
112
112
  - !ruby/object:Gem::Version
113
- version: 1.3.1
113
+ version: '0'
114
114
  requirements: []
115
- rubygems_version: 3.1.4
116
- signing_key:
115
+ rubygems_version: 3.2.22
116
+ signing_key:
117
117
  specification_version: 4
118
118
  summary: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).
119
119
  test_files: []