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 +4 -4
- data/Gemfile +4 -4
- data/README.md +10 -9
- data/Rakefile +2 -2
- data/lib/irb/cmd/history.rb +47 -0
- data/lib/irb/cmd/show_cmds.rb +6 -0
- data/lib/irb/cmd/show_source.rb +9 -2
- data/lib/irb/completion.rb +21 -0
- data/lib/irb/context.rb +22 -14
- data/lib/irb/debug.rb +18 -0
- data/lib/irb/extend-command.rb +6 -0
- data/lib/irb/history.rb +1 -1
- data/lib/irb/init.rb +3 -4
- data/lib/irb/lc/help-message +1 -0
- data/lib/irb/pager.rb +12 -11
- data/lib/irb/source_finder.rb +26 -6
- data/lib/irb/version.rb +2 -2
- data/lib/irb.rb +48 -40
- metadata +3 -7
- data/lib/irb/type_completion/completor.rb +0 -235
- data/lib/irb/type_completion/methods.rb +0 -13
- data/lib/irb/type_completion/scope.rb +0 -412
- data/lib/irb/type_completion/type_analyzer.rb +0 -1169
- data/lib/irb/type_completion/types.rb +0 -426
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0e7153fbd64c519a7af411d95779821c279a63b786c16df0e5cff4b577a258f
|
4
|
+
data.tar.gz: 86c81569fa9788676c575f64b1010191690b4b3c056330e5f21fb798d724924f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
22
|
-
|
23
|
-
|
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::
|
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::
|
243
|
+
### How to Enable IRB::TypeCompletor
|
243
244
|
|
244
|
-
To enable IRB::
|
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
|
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,
|
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::
|
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::
|
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::
|
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::
|
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
|
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
|
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
|
data/lib/irb/cmd/show_cmds.rb
CHANGED
@@ -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")
|
data/lib/irb/cmd/show_source.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/irb/completion.rb
CHANGED
@@ -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
|
-
@
|
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
|
-
|
171
|
-
|
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 '
|
187
|
+
require 'repl_type_completor'
|
176
188
|
rescue LoadError => e
|
177
|
-
warn "
|
189
|
+
warn "TypeCompletor requires `gem repl_type_completor`: #{e.message}"
|
178
190
|
return
|
179
191
|
end
|
180
|
-
|
181
|
-
|
182
|
-
|
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
|
|
data/lib/irb/extend-command.rb
CHANGED
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"
|
data/lib/irb/lc/help-message
CHANGED
@@ -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 |
|
62
|
-
|
63
|
-
next if
|
61
|
+
PAGE_COMMANDS.each do |pager_cmd|
|
62
|
+
cmd = Shellwords.split(pager_cmd)
|
63
|
+
next if cmd.empty?
|
64
64
|
|
65
|
-
if
|
66
|
-
|
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(
|
71
|
+
io = IO.popen(cmd, 'w')
|
71
72
|
rescue
|
72
73
|
next
|
73
74
|
end
|
data/lib/irb/source_finder.rb
CHANGED
@@ -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
|
-
|
30
|
-
|
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
|
-
|
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
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
|
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
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
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
|
-
|
723
|
-
message =
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
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
|
-
|
740
|
-
|
741
|
-
}
|
742
|
-
|
743
|
-
|
744
|
-
|
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
|
-
|
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
|
-
|
935
|
+
main_str = @context.main.to_s rescue "!#{$!.class}"
|
936
|
+
truncate_prompt_main(main_str)
|
930
937
|
when "M"
|
931
|
-
|
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.
|
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-
|
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
|