irb 1.9.1 → 1.10.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ed98e2ce49cea18e608a64f8e5f5e310064a373b944de0474d49e21613b5be6
4
- data.tar.gz: 679dea24c5f90242c1f0f427b42bc0d90caafb6ad8ec73da6d11181bb5645f9f
3
+ metadata.gz: c0e7153fbd64c519a7af411d95779821c279a63b786c16df0e5cff4b577a258f
4
+ data.tar.gz: 86c81569fa9788676c575f64b1010191690b4b3c056330e5f21fb798d724924f
5
5
  SHA512:
6
- metadata.gz: 41a6d57dc51eb6d17c6aa3c7a635d576d4d21d3e5b6eab92becb3862060fae0fdbd34cc0975bca219a7cc6c5808657b417f5aae1dc9606649fe4f82bcce8c467
7
- data.tar.gz: d7499712f5310d00f6a47b8581749c1e34a69fe3984cb3efbe9d1ce1825d65dcfd471e17831cee56ca3dda7d0a17cabc5b36f6511f151c1b7472b9042e9c173f
6
+ metadata.gz: e78e35a1a46ac5b4e62e93f7cac0e1b3657b16cd108851624b3cfd2b6c81662ca6dfa7aff9737d743a625eaa96a47179c95e9af28833dcb9d761ee150923497d
7
+ data.tar.gz: 562c5e88c5c09adbe4f882d30a34b496599af4f7a45f41d60609ef91148d7271cd97bbfd629ca75da4f3845d7815e51bca3b1969e9bff1c723c18b3c0840517d
data/Gemfile CHANGED
@@ -16,9 +16,9 @@ gem "reline", github: "ruby/reline" if ENV["WITH_LATEST_RELINE"] == "true"
16
16
  gem "rake"
17
17
  gem "test-unit"
18
18
  gem "test-unit-ruby-core"
19
- gem "debug", github: "ruby/debug"
20
19
 
21
- if RUBY_VERSION >= "3.0.0"
22
- gem "rbs"
23
- gem "prism", ">= 0.17.1"
20
+ gem "debug", github: "ruby/debug", platforms: [:mri, :mswin]
21
+
22
+ if RUBY_VERSION >= "3.0.0" && !is_truffleruby
23
+ gem "repl_type_completor"
24
24
  end
data/README.md CHANGED
@@ -119,6 +119,7 @@ IRB
119
119
  source Loads a given file in the current session.
120
120
  irb_info Show information about IRB.
121
121
  show_cmds List all available commands and their description.
122
+ history Shows the input history. `-g [query]` or `-G [query]` allows you to filter the output.
122
123
 
123
124
  Multi-irb (DEPRECATED)
124
125
  irb Start a child IRB.
@@ -237,11 +238,11 @@ However, there are also some limitations to be aware of:
237
238
 
238
239
  ## Type Based Completion
239
240
 
240
- IRB's default completion `IRB::RegexpCompletor` uses Regexp. IRB has another experimental completion `IRB::TypeCompletion` that uses type analysis.
241
+ IRB's default completion `IRB::RegexpCompletor` uses Regexp. IRB has another experimental completion `IRB::TypeCompletor` that uses type analysis.
241
242
 
242
- ### How to Enable IRB::TypeCompletion
243
+ ### How to Enable IRB::TypeCompletor
243
244
 
244
- To enable IRB::TypeCompletion, run IRB with `--type-completor` option
245
+ To enable IRB::TypeCompletor, run IRB with `--type-completor` option
245
246
  ```
246
247
  $ irb --type-completor
247
248
  ```
@@ -249,14 +250,14 @@ Or write the code below to IRB's rc-file.
249
250
  ```ruby
250
251
  IRB.conf[:COMPLETOR] = :type # default is :regexp
251
252
  ```
252
- You also need `gem prism` and `gem rbs` to use this feature.
253
+ You also need `gem repl_type_completor` to use this feature.
253
254
 
254
255
  To check if it's enabled, type `irb_info` into IRB and see the `Completion` section.
255
256
  ```
256
257
  irb(main):001> irb_info
257
258
  ...
258
259
  # Enabled
259
- Completion: Autocomplete, TypeCompletion::Completor(Prism: 0.17.1, RBS: 3.3.0)
260
+ Completion: Autocomplete, ReplTypeCompletor: 0.1.0, Prism: 0.18.0, RBS: 3.3.0
260
261
  # Not enabled
261
262
  Completion: Autocomplete, RegexpCompletor
262
263
  ...
@@ -265,7 +266,7 @@ If you have `sig/` directory or `rbs_collection.lock.yaml` in current directory,
265
266
 
266
267
  ### Advantage over Default IRB::RegexpCompletor
267
268
 
268
- IRB::TypeCompletion can autocomplete chained methods, block parameters and more if type information is available.
269
+ IRB::TypeCompletor can autocomplete chained methods, block parameters and more if type information is available.
269
270
  These are some examples IRB::RegexpCompletor cannot complete.
270
271
 
271
272
  ```ruby
@@ -287,11 +288,11 @@ As a trade-off, completion calculation takes more time than IRB::RegexpCompletor
287
288
 
288
289
  ### Difference between Steep's Completion
289
290
 
290
- Compared with Steep, IRB::TypeCompletion has some difference and limitations.
291
+ Compared with Steep, IRB::TypeCompletor has some difference and limitations.
291
292
  ```ruby
292
293
  [0, 'a'].sample.
293
294
  # Steep completes intersection of Integer methods and String methods
294
- # IRB::TypeCompletion completes both Integer and String methods
295
+ # IRB::TypeCompletor completes both Integer and String methods
295
296
  ```
296
297
 
297
298
  Some features like type narrowing is not implemented.
@@ -301,7 +302,7 @@ def f(arg = [0, 'a'].sample)
301
302
  arg. # Completes both Integer and String methods
302
303
  ```
303
304
 
304
- Unlike other static type checker, IRB::TypeCompletion uses runtime information to provide better completion.
305
+ Unlike other static type checker, IRB::TypeCompletor uses runtime information to provide better completion.
305
306
  ```ruby
306
307
  irb(main):001> a = [1]
307
308
  => [1]
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ Rake::TestTask.new(:test) do |t|
5
5
  t.libs << "test" << "test/lib"
6
6
  t.libs << "lib"
7
7
  t.ruby_opts << "-rhelper"
8
- t.test_files = FileList["test/irb/test_*.rb", "test/irb/type_completion/test_*.rb"]
8
+ t.test_files = FileList["test/irb/**/test_*.rb"]
9
9
  end
10
10
 
11
11
  # To make sure they have been correctly setup for Ruby CI.
@@ -13,7 +13,7 @@ desc "Run each irb test file in isolation."
13
13
  task :test_in_isolation do
14
14
  failed = false
15
15
 
16
- FileList["test/irb/test_*.rb", "test/irb/type_completion/test_*.rb"].each do |test_file|
16
+ FileList["test/irb/**/test_*.rb"].each do |test_file|
17
17
  ENV["TEST"] = test_file
18
18
  begin
19
19
  Rake::Task["test"].execute
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
4
+ require_relative "nop"
5
+ require_relative "../pager"
6
+
7
+ module IRB
8
+ # :stopdoc:
9
+
10
+ module ExtendCommand
11
+ class History < Nop
12
+ category "IRB"
13
+ description "Shows the input history. `-g [query]` or `-G [query]` allows you to filter the output."
14
+
15
+ def self.transform_args(args)
16
+ match = args&.match(/(-g|-G)\s+(?<grep>.+)\s*\n\z/)
17
+ return unless match
18
+
19
+ "grep: #{Regexp.new(match[:grep]).inspect}"
20
+ end
21
+
22
+ def execute(grep: nil)
23
+ formatted_inputs = irb_context.io.class::HISTORY.each_with_index.reverse_each.filter_map do |input, index|
24
+ next if grep && !input.match?(grep)
25
+
26
+ header = "#{index}: "
27
+
28
+ first_line, *other_lines = input.split("\n")
29
+ first_line = "#{header}#{first_line}"
30
+
31
+ truncated_lines = other_lines.slice!(1..) # Show 1 additional line (2 total)
32
+ other_lines << "..." if truncated_lines&.any?
33
+
34
+ other_lines.map! do |line|
35
+ " " * header.length + line
36
+ end
37
+
38
+ [first_line, *other_lines].join("\n") + "\n"
39
+ end
40
+
41
+ Pager.page_content(formatted_inputs.join)
42
+ end
43
+ end
44
+ end
45
+
46
+ # :startdoc:
47
+ end
@@ -16,6 +16,12 @@ module IRB
16
16
  commands_info = IRB::ExtendCommandBundle.all_commands_info
17
17
  commands_grouped_by_categories = commands_info.group_by { |cmd| cmd[:category] }
18
18
 
19
+ user_aliases = irb_context.instance_variable_get(:@user_aliases)
20
+
21
+ commands_grouped_by_categories["Aliases"] = user_aliases.map do |alias_name, target|
22
+ { display_name: alias_name, description: "Alias for `#{target}`" }
23
+ end
24
+
19
25
  if irb_context.with_debugger
20
26
  # Remove the original "Debugging" category
21
27
  commands_grouped_by_categories.delete("Debugging")
@@ -27,11 +27,18 @@ module IRB
27
27
  puts "Error: Expected a string but got #{str.inspect}"
28
28
  return
29
29
  end
30
-
31
- source = SourceFinder.new(@irb_context).find_source(str)
30
+ if str.include? " -s"
31
+ str, esses = str.split(" -")
32
+ s_count = esses.count("^s").zero? ? esses.size : 1
33
+ source = SourceFinder.new(@irb_context).find_source(str, s_count)
34
+ else
35
+ source = SourceFinder.new(@irb_context).find_source(str)
36
+ end
32
37
 
33
38
  if source
34
39
  show_source(source)
40
+ elsif s_count
41
+ puts "Error: Couldn't locate a super definition for #{str}"
35
42
  else
36
43
  puts "Error: Couldn't locate a definition for #{str}"
37
44
  end
@@ -93,6 +93,27 @@ module IRB
93
93
  end
94
94
  end
95
95
 
96
+ class TypeCompletor < BaseCompletor # :nodoc:
97
+ def initialize(context)
98
+ @context = context
99
+ end
100
+
101
+ def inspect
102
+ ReplTypeCompletor.info
103
+ end
104
+
105
+ def completion_candidates(preposing, target, _postposing, bind:)
106
+ result = ReplTypeCompletor.analyze(preposing + target, binding: bind, filename: @context.irb_path)
107
+ return [] unless result
108
+ result.completion_candidates.map { target + _1 }
109
+ end
110
+
111
+ def doc_namespace(preposing, matched, _postposing, bind:)
112
+ result = ReplTypeCompletor.analyze(preposing + matched, binding: bind, filename: @context.irb_path)
113
+ result&.doc_namespace('')
114
+ end
115
+ end
116
+
96
117
  class RegexpCompletor < BaseCompletor # :nodoc:
97
118
  using Module.new {
98
119
  refine ::Binding do
data/lib/irb/context.rb CHANGED
@@ -146,9 +146,21 @@ module IRB
146
146
  @newline_before_multiline_output = true
147
147
  end
148
148
 
149
- @command_aliases = IRB.conf[:COMMAND_ALIASES]
149
+ @user_aliases = IRB.conf[:COMMAND_ALIASES].dup
150
+ @command_aliases = @user_aliases.merge(KEYWORD_ALIASES)
150
151
  end
151
152
 
153
+ # because all input will eventually be evaluated as Ruby code,
154
+ # command names that conflict with Ruby keywords need special workaround
155
+ # we can remove them once we implemented a better command system for IRB
156
+ KEYWORD_ALIASES = {
157
+ :break => :irb_break,
158
+ :catch => :irb_catch,
159
+ :next => :irb_next,
160
+ }.freeze
161
+
162
+ private_constant :KEYWORD_ALIASES
163
+
152
164
  private def build_completor
153
165
  completor_type = IRB.conf[:COMPLETOR]
154
166
  case completor_type
@@ -164,26 +176,22 @@ module IRB
164
176
  RegexpCompletor.new
165
177
  end
166
178
 
167
- TYPE_COMPLETION_REQUIRED_PRISM_VERSION = '0.17.1'
168
-
169
179
  private def build_type_completor
170
- unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0') && RUBY_ENGINE != 'truffleruby'
171
- warn 'TypeCompletion requires RUBY_VERSION >= 3.0.0'
180
+ if RUBY_ENGINE == 'truffleruby'
181
+ # Avoid SynatxError. truffleruby does not support endless method definition yet.
182
+ warn 'TypeCompletor is not supported on TruffleRuby yet'
172
183
  return
173
184
  end
185
+
174
186
  begin
175
- require 'prism'
187
+ require 'repl_type_completor'
176
188
  rescue LoadError => e
177
- warn "TypeCompletion requires Prism: #{e.message}"
189
+ warn "TypeCompletor requires `gem repl_type_completor`: #{e.message}"
178
190
  return
179
191
  end
180
- unless Gem::Version.new(Prism::VERSION) >= Gem::Version.new(TYPE_COMPLETION_REQUIRED_PRISM_VERSION)
181
- warn "TypeCompletion requires Prism::VERSION >= #{TYPE_COMPLETION_REQUIRED_PRISM_VERSION}"
182
- return
183
- end
184
- require 'irb/type_completion/completor'
185
- TypeCompletion::Types.preload_in_thread
186
- TypeCompletion::Completor.new
192
+
193
+ ReplTypeCompletor.preload_rbs
194
+ TypeCompletor.new(self)
187
195
  end
188
196
 
189
197
  def save_history=(val)
data/lib/irb/debug.rb CHANGED
@@ -57,6 +57,24 @@ module IRB
57
57
  DEBUGGER__::ThreadClient.prepend(SkipPathHelperForIRB)
58
58
  end
59
59
 
60
+ if !@output_modifier_defined && !DEBUGGER__::CONFIG[:no_hint]
61
+ irb_output_modifier_proc = Reline.output_modifier_proc
62
+
63
+ Reline.output_modifier_proc = proc do |output, complete:|
64
+ unless output.strip.empty?
65
+ cmd = output.split(/\s/, 2).first
66
+
67
+ if !complete && DEBUGGER__.commands.key?(cmd)
68
+ output = output.sub(/\n$/, " # debug command\n")
69
+ end
70
+ end
71
+
72
+ irb_output_modifier_proc.call(output, complete: complete)
73
+ end
74
+
75
+ @output_modifier_defined = true
76
+ end
77
+
60
78
  true
61
79
  end
62
80
 
@@ -191,6 +191,12 @@ module IRB # :nodoc:
191
191
  [
192
192
  :irb_show_cmds, :ShowCmds, "cmd/show_cmds",
193
193
  [:show_cmds, NO_OVERRIDE],
194
+ ],
195
+
196
+ [
197
+ :irb_history, :History, "cmd/history",
198
+ [:history, NO_OVERRIDE],
199
+ [:hist, NO_OVERRIDE],
194
200
  ]
195
201
  ]
196
202
 
data/lib/irb/history.rb CHANGED
@@ -60,7 +60,7 @@ module IRB
60
60
  end
61
61
 
62
62
  File.open(history_file, (append_history ? 'a' : 'w'), 0o600, encoding: IRB.conf[:LC_MESSAGES]&.encoding) do |f|
63
- hist = history.map{ |l| l.split("\n").join("\\\n") }
63
+ hist = history.map{ |l| l.scrub.split("\n").join("\\\n") }
64
64
  unless append_history
65
65
  begin
66
66
  hist = hist.last(num) if hist.size > num and num > 0
data/lib/irb/init.rb CHANGED
@@ -82,6 +82,7 @@ module IRB # :nodoc:
82
82
  @CONF[:USE_LOADER] = false
83
83
  @CONF[:IGNORE_SIGINT] = true
84
84
  @CONF[:IGNORE_EOF] = false
85
+ @CONF[:USE_PAGER] = true
85
86
  @CONF[:EXTRA_DOC_DIRS] = []
86
87
  @CONF[:ECHO] = nil
87
88
  @CONF[:ECHO_ON_ASSIGNMENT] = nil
@@ -188,10 +189,6 @@ module IRB # :nodoc:
188
189
  # Symbol aliases
189
190
  :'$' => :show_source,
190
191
  :'@' => :whereami,
191
- # Keyword aliases
192
- :break => :irb_break,
193
- :catch => :irb_catch,
194
- :next => :irb_next,
195
192
  }
196
193
  end
197
194
 
@@ -285,6 +282,8 @@ module IRB # :nodoc:
285
282
  end
286
283
  when "--noinspect"
287
284
  @CONF[:INSPECT_MODE] = false
285
+ when "--no-pager"
286
+ @CONF[:USE_PAGER] = false
288
287
  when "--singleline", "--readline", "--legacy"
289
288
  @CONF[:USE_SINGLELINE] = true
290
289
  when "--nosingleline", "--noreadline"
@@ -22,6 +22,7 @@ Usage: irb.rb [options] [programfile] [arguments]
22
22
  Show truncated result on assignment (default).
23
23
  --inspect Use 'inspect' for output.
24
24
  --noinspect Don't use 'inspect' for output.
25
+ --no-pager Don't use pager.
25
26
  --multiline Use multiline editor module (default).
26
27
  --nomultiline Don't use multiline editor module.
27
28
  --singleline Use single line editor module.
data/lib/irb/pager.rb CHANGED
@@ -7,9 +7,9 @@ module IRB
7
7
  PAGE_COMMANDS = [ENV['RI_PAGER'], ENV['PAGER'], 'less', 'more'].compact.uniq
8
8
 
9
9
  class << self
10
- def page_content(content)
10
+ def page_content(content, **options)
11
11
  if content_exceeds_screen_height?(content)
12
- page do |io|
12
+ page(**options) do |io|
13
13
  io.puts content
14
14
  end
15
15
  else
@@ -17,8 +17,8 @@ module IRB
17
17
  end
18
18
  end
19
19
 
20
- def page
21
- if STDIN.tty? && pager = setup_pager
20
+ def page(retain_content: false)
21
+ if IRB.conf[:USE_PAGER] && STDIN.tty? && pager = setup_pager(retain_content: retain_content)
22
22
  begin
23
23
  pid = pager.pid
24
24
  yield pager
@@ -55,19 +55,20 @@ module IRB
55
55
  pageable_height * screen_width < Reline::Unicode.calculate_width(content, true)
56
56
  end
57
57
 
58
- def setup_pager
58
+ def setup_pager(retain_content:)
59
59
  require 'shellwords'
60
60
 
61
- PAGE_COMMANDS.each do |pager|
62
- pager = Shellwords.split(pager)
63
- next if pager.empty?
61
+ PAGE_COMMANDS.each do |pager_cmd|
62
+ cmd = Shellwords.split(pager_cmd)
63
+ next if cmd.empty?
64
64
 
65
- if pager.first == 'less' || pager.first == 'more'
66
- pager << '-R' unless pager.include?('-R')
65
+ if cmd.first == 'less'
66
+ cmd << '-R' unless cmd.include?('-R')
67
+ cmd << '-X' if retain_content && !cmd.include?('-X')
67
68
  end
68
69
 
69
70
  begin
70
- io = IO.popen(pager, 'w')
71
+ io = IO.popen(cmd, 'w')
71
72
  rescue
72
73
  next
73
74
  end
@@ -16,7 +16,7 @@ module IRB
16
16
  @irb_context = irb_context
17
17
  end
18
18
 
19
- def find_source(signature)
19
+ def find_source(signature, s_count = nil)
20
20
  context_binding = @irb_context.workspace.binding
21
21
  case signature
22
22
  when /\A[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name
@@ -26,14 +26,13 @@ module IRB
26
26
  when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
27
27
  owner = eval(Regexp.last_match[:owner], context_binding)
28
28
  method = Regexp.last_match[:method]
29
- if owner.respond_to?(:instance_method)
30
- methods = owner.instance_methods + owner.private_instance_methods
31
- file, line = owner.instance_method(method).source_location if methods.include?(method.to_sym)
32
- end
29
+ return unless owner.respond_to?(:instance_method)
30
+ file, line = method_target(owner, s_count, method, "owner")
33
31
  when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method
34
32
  receiver = eval(Regexp.last_match[:receiver] || 'self', context_binding)
35
33
  method = Regexp.last_match[:method]
36
- file, line = receiver.method(method).source_location if receiver.respond_to?(method, true)
34
+ return unless receiver.respond_to?(method, true)
35
+ file, line = method_target(receiver, s_count, method, "receiver")
37
36
  end
38
37
  if file && line && File.exist?(file)
39
38
  Source.new(file: file, first_line: line, last_line: find_end(file, line))
@@ -60,5 +59,26 @@ module IRB
60
59
  end
61
60
  first_line
62
61
  end
62
+
63
+ def method_target(owner_receiver, s_count, method, type)
64
+ case type
65
+ when "owner"
66
+ target_method = owner_receiver.instance_method(method)
67
+ return target_method.source_location unless s_count
68
+ when "receiver"
69
+ if s_count
70
+ target_method = owner_receiver.class.instance_method(method)
71
+ else
72
+ target_method = method
73
+ return owner_receiver.method(method).source_location
74
+ end
75
+ end
76
+ s_count.times do |s|
77
+ target_method = target_method.super_method if target_method
78
+ end
79
+ target_method.nil? ? nil : target_method.source_location
80
+ rescue NameError
81
+ nil
82
+ end
63
83
  end
64
84
  end
data/lib/irb/version.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  #
6
6
 
7
7
  module IRB # :nodoc:
8
- VERSION = "1.9.1"
8
+ VERSION = "1.10.0"
9
9
  @RELEASE_VERSION = VERSION
10
- @LAST_UPDATE_DATE = "2023-11-21"
10
+ @LAST_UPDATE_DATE = "2023-12-03"
11
11
  end
data/lib/irb.rb CHANGED
@@ -20,6 +20,7 @@ require_relative "irb/color"
20
20
  require_relative "irb/version"
21
21
  require_relative "irb/easter-egg"
22
22
  require_relative "irb/debug"
23
+ require_relative "irb/pager"
23
24
 
24
25
  # IRB stands for "interactive Ruby" and is a tool to interactively execute Ruby
25
26
  # expressions read from the standard input.
@@ -697,7 +698,7 @@ module IRB
697
698
  end
698
699
 
699
700
  def handle_exception(exc)
700
- if exc.backtrace && exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
701
+ if exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
701
702
  !(SyntaxError === exc) && !(EncodingError === exc)
702
703
  # The backtrace of invalid encoding hash (ex. {"\xAE": 1}) raises EncodingError without lineno.
703
704
  irb_bug = true
@@ -705,45 +706,49 @@ module IRB
705
706
  irb_bug = false
706
707
  end
707
708
 
708
- if exc.backtrace
709
- order = nil
710
- if RUBY_VERSION < '3.0.0'
711
- if STDOUT.tty?
712
- message = exc.full_message(order: :bottom)
713
- order = :bottom
714
- else
715
- message = exc.full_message(order: :top)
716
- order = :top
717
- end
718
- else # '3.0.0' <= RUBY_VERSION
709
+ if RUBY_VERSION < '3.0.0'
710
+ if STDOUT.tty?
711
+ message = exc.full_message(order: :bottom)
712
+ order = :bottom
713
+ else
719
714
  message = exc.full_message(order: :top)
720
715
  order = :top
721
716
  end
722
- message = convert_invalid_byte_sequence(message, exc.message.encoding)
723
- message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) unless message.encoding.to_s.casecmp?(IRB.conf[:LC_MESSAGES].encoding.to_s)
724
- message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
725
- case order
726
- when :top
727
- lines = m.split("\n")
728
- when :bottom
729
- lines = m.split("\n").reverse
730
- end
731
- unless irb_bug
732
- lines = lines.map { |l| @context.workspace.filter_backtrace(l) }.compact
733
- if lines.size > @context.back_trace_limit
734
- omit = lines.size - @context.back_trace_limit
735
- lines = lines[0..(@context.back_trace_limit - 1)]
736
- lines << "\t... %d levels..." % omit
737
- end
717
+ else # '3.0.0' <= RUBY_VERSION
718
+ message = exc.full_message(order: :top)
719
+ order = :top
720
+ end
721
+ message = convert_invalid_byte_sequence(message, exc.message.encoding)
722
+ message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) unless message.encoding.to_s.casecmp?(IRB.conf[:LC_MESSAGES].encoding.to_s)
723
+ message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
724
+ case order
725
+ when :top
726
+ lines = m.split("\n")
727
+ when :bottom
728
+ lines = m.split("\n").reverse
729
+ end
730
+ unless irb_bug
731
+ lines = lines.map { |l| @context.workspace.filter_backtrace(l) }.compact
732
+ if lines.size > @context.back_trace_limit
733
+ omit = lines.size - @context.back_trace_limit
734
+ lines = lines[0..(@context.back_trace_limit - 1)]
735
+ lines << "\t... %d levels..." % omit
738
736
  end
739
- lines = lines.reverse if order == :bottom
740
- lines.map{ |l| l + "\n" }.join
741
- }
742
- # The "<top (required)>" in "(irb)" may be the top level of IRB so imitate the main object.
743
- message = message.gsub(/\(irb\):(?<num>\d+):in `<(?<frame>top \(required\))>'/) { "(irb):#{$~[:num]}:in `<main>'" }
744
- puts message
737
+ end
738
+ lines = lines.reverse if order == :bottom
739
+ lines.map{ |l| l + "\n" }.join
740
+ }
741
+ # The "<top (required)>" in "(irb)" may be the top level of IRB so imitate the main object.
742
+ message = message.gsub(/\(irb\):(?<num>\d+):in `<(?<frame>top \(required\))>'/) { "(irb):#{$~[:num]}:in `<main>'" }
743
+ puts message
744
+ puts 'Maybe IRB bug!' if irb_bug
745
+ rescue Exception => handler_exc
746
+ begin
747
+ puts exc.inspect
748
+ puts "backtraces are hidden because #{handler_exc} was raised when processing them"
749
+ rescue Exception
750
+ puts 'Uninspectable exception occurred'
745
751
  end
746
- print "Maybe IRB bug!\n" if irb_bug
747
752
  end
748
753
 
749
754
  # Evaluates the given block using the given +path+ as the Context#irb_path
@@ -855,11 +860,12 @@ module IRB
855
860
  end
856
861
  end
857
862
  end
863
+
858
864
  if multiline_p && @context.newline_before_multiline_output?
859
- printf @context.return_format, "\n#{str}"
860
- else
861
- printf @context.return_format, str
865
+ str = "\n" + str
862
866
  end
867
+
868
+ Pager.page_content(format(@context.return_format, str), retain_content: true)
863
869
  end
864
870
 
865
871
  # Outputs the local variables to this current session, including
@@ -926,9 +932,11 @@ module IRB
926
932
  when "N"
927
933
  @context.irb_name
928
934
  when "m"
929
- truncate_prompt_main(@context.main.to_s)
935
+ main_str = @context.main.to_s rescue "!#{$!.class}"
936
+ truncate_prompt_main(main_str)
930
937
  when "M"
931
- truncate_prompt_main(@context.main.inspect)
938
+ main_str = @context.main.inspect rescue "!#{$!.class}"
939
+ truncate_prompt_main(main_str)
932
940
  when "l"
933
941
  ltype
934
942
  when "i"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: irb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.1
4
+ version: 1.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - aycabta
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2023-11-21 00:00:00.000000000 Z
12
+ date: 2023-12-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: reline
@@ -70,6 +70,7 @@ files:
70
70
  - lib/irb/cmd/edit.rb
71
71
  - lib/irb/cmd/finish.rb
72
72
  - lib/irb/cmd/help.rb
73
+ - lib/irb/cmd/history.rb
73
74
  - lib/irb/cmd/info.rb
74
75
  - lib/irb/cmd/irb_info.rb
75
76
  - lib/irb/cmd/load.rb
@@ -118,11 +119,6 @@ files:
118
119
  - lib/irb/ruby_logo.aa
119
120
  - lib/irb/source_finder.rb
120
121
  - lib/irb/statement.rb
121
- - lib/irb/type_completion/completor.rb
122
- - lib/irb/type_completion/methods.rb
123
- - lib/irb/type_completion/scope.rb
124
- - lib/irb/type_completion/type_analyzer.rb
125
- - lib/irb/type_completion/types.rb
126
122
  - lib/irb/version.rb
127
123
  - lib/irb/workspace.rb
128
124
  - lib/irb/ws-for-case-2.rb