irb 1.14.3 → 1.16.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/.rdoc_options +5 -0
- data/CONTRIBUTING.md +52 -0
- data/EXTEND_IRB.md +3 -0
- data/Gemfile +5 -1
- data/README.md +13 -310
- data/doc/COMMAND_LINE_OPTIONS.md +69 -0
- data/doc/COMPARED_WITH_PRY.md +22 -0
- data/doc/Configurations.md +274 -0
- data/doc/EXTEND_IRB.md +122 -0
- data/doc/Index.md +705 -0
- data/doc/irb/irb.rd.ja +1 -1
- data/lib/irb/color.rb +1 -0
- data/lib/irb/color_printer.rb +10 -9
- data/lib/irb/command/copy.rb +73 -0
- data/lib/irb/command/history.rb +1 -1
- data/lib/irb/completion.rb +31 -36
- data/lib/irb/context.rb +99 -63
- data/lib/irb/debug.rb +2 -2
- data/lib/irb/default_commands.rb +4 -1
- data/lib/irb/easter-egg.rb +3 -1
- data/lib/irb/ext/multi-irb.rb +2 -0
- data/lib/irb/history.rb +4 -0
- data/lib/irb/init.rb +3 -1
- data/lib/irb/input-method.rb +17 -11
- data/lib/irb/inspector.rb +12 -7
- data/lib/irb/lc/help-message +2 -2
- data/lib/irb/lc/ja/help-message +1 -1
- data/lib/irb/pager.rb +119 -6
- data/lib/irb/ruby-lex.rb +25 -0
- data/lib/irb/source_finder.rb +7 -4
- data/lib/irb/statement.rb +21 -0
- data/lib/irb/version.rb +2 -2
- data/lib/irb/workspace.rb +9 -0
- data/lib/irb.rb +73 -910
- data/man/irb.1 +2 -0
- metadata +27 -12
- data/.document +0 -8
- data/Rakefile +0 -52
- data/bin/console +0 -6
- data/bin/setup +0 -6
- data/irb.gemspec +0 -46
data/lib/irb/inspector.rb
CHANGED
|
@@ -46,7 +46,7 @@ module IRB # :nodoc:
|
|
|
46
46
|
# Determines the inspector to use where +inspector+ is one of the keys passed
|
|
47
47
|
# during inspector definition.
|
|
48
48
|
def keys_with_inspector(inspector)
|
|
49
|
-
INSPECTORS.
|
|
49
|
+
INSPECTORS.filter_map {|k, v| k if v == inspector}
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
# Example
|
|
@@ -92,9 +92,14 @@ module IRB # :nodoc:
|
|
|
92
92
|
@init.call if @init
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
+
def support_stream_output?
|
|
96
|
+
second_parameter_type = @inspect.parameters[1]&.first
|
|
97
|
+
second_parameter_type == :req || second_parameter_type == :opt
|
|
98
|
+
end
|
|
99
|
+
|
|
95
100
|
# Proc to call when the input is evaluated and output in irb.
|
|
96
|
-
def inspect_value(v)
|
|
97
|
-
@inspect.call(v)
|
|
101
|
+
def inspect_value(v, output, colorize: true)
|
|
102
|
+
support_stream_output? ? @inspect.call(v, output, colorize: colorize) : output << @inspect.call(v, colorize: colorize)
|
|
98
103
|
rescue => e
|
|
99
104
|
puts "An error occurred when inspecting the object: #{e.inspect}"
|
|
100
105
|
|
|
@@ -110,11 +115,11 @@ module IRB # :nodoc:
|
|
|
110
115
|
end
|
|
111
116
|
|
|
112
117
|
Inspector.def_inspector([false, :to_s, :raw]){|v| v.to_s}
|
|
113
|
-
Inspector.def_inspector([:p, :inspect]){|v|
|
|
114
|
-
Color.colorize_code(v.inspect, colorable: Color.colorable? && Color.inspect_colorable?(v))
|
|
118
|
+
Inspector.def_inspector([:p, :inspect]){|v, colorize: true|
|
|
119
|
+
Color.colorize_code(v.inspect, colorable: colorize && Color.colorable? && Color.inspect_colorable?(v))
|
|
115
120
|
}
|
|
116
|
-
Inspector.def_inspector([true, :pp, :pretty_inspect], proc{require_relative "color_printer"}){|v|
|
|
117
|
-
IRB::ColorPrinter.pp(v,
|
|
121
|
+
Inspector.def_inspector([true, :pp, :pretty_inspect], proc{require_relative "color_printer"}){|v, output, colorize: true|
|
|
122
|
+
IRB::ColorPrinter.pp(v, output, colorize: colorize)
|
|
118
123
|
}
|
|
119
124
|
Inspector.def_inspector([:yaml, :YAML], proc{require "yaml"}){|v|
|
|
120
125
|
begin
|
data/lib/irb/lc/help-message
CHANGED
|
@@ -6,10 +6,10 @@ Usage: irb.rb [options] [programfile] [arguments]
|
|
|
6
6
|
-U Set external and internal encodings to UTF-8.
|
|
7
7
|
-E ex[:in] Set default external (ex) and internal (in) encodings
|
|
8
8
|
(same as 'ruby -E').
|
|
9
|
-
-w
|
|
9
|
+
-w Enable warnings (same as 'ruby -w' or 'ruby -W1').
|
|
10
10
|
-W[level=2] Set warning level: 0=silence, 1=medium, 2=verbose
|
|
11
11
|
(same as 'ruby -W').
|
|
12
|
-
--context-mode n Set n[0-
|
|
12
|
+
--context-mode n Set n[0-5] to method to create Binding Object,
|
|
13
13
|
when new workspace was created.
|
|
14
14
|
--extra-doc-dir Add an extra doc dir for the doc dialog.
|
|
15
15
|
--echo Show result (default).
|
data/lib/irb/lc/ja/help-message
CHANGED
|
@@ -8,7 +8,7 @@ Usage: irb.rb [options] [programfile] [arguments]
|
|
|
8
8
|
-w ruby -w と同じ.
|
|
9
9
|
-W[level=2] ruby -W と同じ.
|
|
10
10
|
--context-mode n 新しいワークスペースを作成した時に関連する Binding
|
|
11
|
-
オブジェクトの作成方法を 0 から
|
|
11
|
+
オブジェクトの作成方法を 0 から 5 のいずれかに設定する.
|
|
12
12
|
--extra-doc-dir 指定したディレクトリのドキュメントを追加で読み込む.
|
|
13
13
|
--echo 実行結果を表示する(デフォルト).
|
|
14
14
|
--noecho 実行結果を表示しない.
|
data/lib/irb/pager.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'reline'
|
|
4
|
+
|
|
3
5
|
module IRB
|
|
4
6
|
# The implementation of this class is borrowed from RDoc's lib/rdoc/ri/driver.rb.
|
|
5
7
|
# Please do NOT use this class directly outside of IRB.
|
|
@@ -47,12 +49,42 @@ module IRB
|
|
|
47
49
|
rescue Errno::EPIPE
|
|
48
50
|
end
|
|
49
51
|
|
|
50
|
-
private
|
|
51
|
-
|
|
52
52
|
def should_page?
|
|
53
53
|
IRB.conf[:USE_PAGER] && STDIN.tty? && (ENV.key?("TERM") && ENV["TERM"] != "dumb")
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
def page_with_preview(width, height, formatter_proc)
|
|
57
|
+
overflow_callback = ->(lines) do
|
|
58
|
+
modified_output = formatter_proc.call(lines.join, true)
|
|
59
|
+
content, = take_first_page(width, [height - 2, 0].max) {|o| o.write modified_output }
|
|
60
|
+
content = content.chomp
|
|
61
|
+
content = "#{content}\e[0m" if Color.colorable?
|
|
62
|
+
$stdout.puts content
|
|
63
|
+
$stdout.puts 'Preparing full inspection value...'
|
|
64
|
+
end
|
|
65
|
+
out = PageOverflowIO.new(width, height, overflow_callback, delay: 0.1)
|
|
66
|
+
yield out
|
|
67
|
+
content = formatter_proc.call(out.string, out.multipage?)
|
|
68
|
+
if out.multipage?
|
|
69
|
+
page(retain_content: true) do |io|
|
|
70
|
+
io.puts content
|
|
71
|
+
end
|
|
72
|
+
else
|
|
73
|
+
$stdout.puts content
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def take_first_page(width, height)
|
|
78
|
+
overflow_callback = proc do |lines|
|
|
79
|
+
return lines.join, true
|
|
80
|
+
end
|
|
81
|
+
out = Pager::PageOverflowIO.new(width, height, overflow_callback)
|
|
82
|
+
yield out
|
|
83
|
+
[out.string, false]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
56
88
|
def content_exceeds_screen_height?(content)
|
|
57
89
|
screen_height, screen_width = begin
|
|
58
90
|
Reline.get_screen_size
|
|
@@ -62,10 +94,10 @@ module IRB
|
|
|
62
94
|
|
|
63
95
|
pageable_height = screen_height - 3 # leave some space for previous and the current prompt
|
|
64
96
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
97
|
+
return true if content.lines.size > pageable_height
|
|
98
|
+
|
|
99
|
+
_, overflow = take_first_page(screen_width, pageable_height) {|out| out.write content }
|
|
100
|
+
overflow
|
|
69
101
|
end
|
|
70
102
|
|
|
71
103
|
def setup_pager(retain_content:)
|
|
@@ -96,5 +128,86 @@ module IRB
|
|
|
96
128
|
nil
|
|
97
129
|
end
|
|
98
130
|
end
|
|
131
|
+
|
|
132
|
+
# Writable IO that has page overflow callback
|
|
133
|
+
class PageOverflowIO
|
|
134
|
+
attr_reader :string, :first_page_lines
|
|
135
|
+
|
|
136
|
+
# Maximum size of a single cell in terminal
|
|
137
|
+
# Assumed worst case: "\e[1;3;4;9;38;2;255;128;128;48;2;128;128;255mA\e[0m"
|
|
138
|
+
# bold, italic, underline, crossed_out, RGB forgound, RGB background
|
|
139
|
+
MAX_CHAR_PER_CELL = 50
|
|
140
|
+
|
|
141
|
+
def initialize(width, height, overflow_callback, delay: nil)
|
|
142
|
+
@lines = []
|
|
143
|
+
@first_page_lines = nil
|
|
144
|
+
@width = width
|
|
145
|
+
@height = height
|
|
146
|
+
@buffer = +''
|
|
147
|
+
@overflow_callback = overflow_callback
|
|
148
|
+
@col = 0
|
|
149
|
+
@string = +''
|
|
150
|
+
@multipage = false
|
|
151
|
+
@delay_until = (Time.now + delay if delay)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def puts(text = '')
|
|
155
|
+
text = text.to_s unless text.is_a?(String)
|
|
156
|
+
write(text)
|
|
157
|
+
write("\n") unless text.end_with?("\n")
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def write(text)
|
|
161
|
+
text = text.to_s unless text.is_a?(String)
|
|
162
|
+
@string << text
|
|
163
|
+
if @multipage
|
|
164
|
+
if @delay_until && Time.now > @delay_until
|
|
165
|
+
@overflow_callback.call(@first_page_lines)
|
|
166
|
+
@delay_until = nil
|
|
167
|
+
end
|
|
168
|
+
return
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
overflow_size = (@width * (@height - @lines.size) + @width - @col) * MAX_CHAR_PER_CELL
|
|
172
|
+
if text.size >= overflow_size
|
|
173
|
+
text = text[0, overflow_size]
|
|
174
|
+
overflow = true
|
|
175
|
+
end
|
|
176
|
+
@buffer << text
|
|
177
|
+
@col += Reline::Unicode.calculate_width(text, true)
|
|
178
|
+
if text.include?("\n") || @col >= @width
|
|
179
|
+
@buffer.lines.each do |line|
|
|
180
|
+
wrapped_lines = Reline::Unicode.split_by_width(line.chomp, @width).first.compact
|
|
181
|
+
wrapped_lines.pop if wrapped_lines.last == ''
|
|
182
|
+
@lines.concat(wrapped_lines)
|
|
183
|
+
if line.end_with?("\n")
|
|
184
|
+
if @lines.empty? || @lines.last.end_with?("\n")
|
|
185
|
+
@lines << "\n"
|
|
186
|
+
else
|
|
187
|
+
@lines[-1] += "\n"
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
@buffer.clear
|
|
192
|
+
@buffer << @lines.pop if !@lines.empty? && !@lines.last.end_with?("\n")
|
|
193
|
+
@col = Reline::Unicode.calculate_width(@buffer, true)
|
|
194
|
+
end
|
|
195
|
+
if overflow || @lines.size > @height || (@lines.size == @height && @col > 0)
|
|
196
|
+
@first_page_lines = @lines.take(@height)
|
|
197
|
+
if !@delay_until || Time.now > @delay_until
|
|
198
|
+
@overflow_callback.call(@first_page_lines)
|
|
199
|
+
@delay_until = nil
|
|
200
|
+
end
|
|
201
|
+
@multipage = true
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def multipage?
|
|
206
|
+
@multipage
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
alias print write
|
|
210
|
+
alias << write
|
|
211
|
+
end
|
|
99
212
|
end
|
|
100
213
|
end
|
data/lib/irb/ruby-lex.rb
CHANGED
|
@@ -52,6 +52,27 @@ module IRB
|
|
|
52
52
|
on_words_beg on_qwords_beg
|
|
53
53
|
]
|
|
54
54
|
|
|
55
|
+
RESERVED_WORDS = %i[
|
|
56
|
+
__ENCODING__ __LINE__ __FILE__
|
|
57
|
+
BEGIN END
|
|
58
|
+
alias and
|
|
59
|
+
begin break
|
|
60
|
+
case class
|
|
61
|
+
def defined? do
|
|
62
|
+
else elsif end ensure
|
|
63
|
+
false for
|
|
64
|
+
if in
|
|
65
|
+
module
|
|
66
|
+
next nil not
|
|
67
|
+
or
|
|
68
|
+
redo rescue retry return
|
|
69
|
+
self super
|
|
70
|
+
then true
|
|
71
|
+
undef unless until
|
|
72
|
+
when while
|
|
73
|
+
yield
|
|
74
|
+
]
|
|
75
|
+
|
|
55
76
|
class TerminateLineInput < StandardError
|
|
56
77
|
def initialize
|
|
57
78
|
super("Terminate Line Input")
|
|
@@ -77,6 +98,10 @@ module IRB
|
|
|
77
98
|
end
|
|
78
99
|
|
|
79
100
|
def generate_local_variables_assign_code(local_variables)
|
|
101
|
+
# Some reserved words could be a local variable
|
|
102
|
+
# Example: def f(if: 1); binding.irb; end
|
|
103
|
+
# These reserved words should be removed from assignment code
|
|
104
|
+
local_variables -= RESERVED_WORDS
|
|
80
105
|
"#{local_variables.join('=')}=nil;" unless local_variables.empty?
|
|
81
106
|
end
|
|
82
107
|
|
data/lib/irb/source_finder.rb
CHANGED
|
@@ -29,10 +29,13 @@ module IRB
|
|
|
29
29
|
|
|
30
30
|
def colorized_content
|
|
31
31
|
if !binary_file? && file_exist?
|
|
32
|
-
end_line = find_end
|
|
33
32
|
# To correctly colorize, we need to colorize full content and extract the relevant lines.
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
colored_lines = IRB::Color.colorize_code(file_content).lines
|
|
34
|
+
|
|
35
|
+
# Handle wrong line number case: line_no passed to eval is wrong, file is edited after load, etc
|
|
36
|
+
return if colored_lines.size < @line
|
|
37
|
+
|
|
38
|
+
colored_lines[@line - 1...find_end].join
|
|
36
39
|
elsif @ast_source
|
|
37
40
|
IRB::Color.colorize_code(@ast_source)
|
|
38
41
|
end
|
|
@@ -114,7 +117,7 @@ module IRB
|
|
|
114
117
|
when "owner"
|
|
115
118
|
target_method = owner_receiver.instance_method(method)
|
|
116
119
|
when "receiver"
|
|
117
|
-
target_method =
|
|
120
|
+
target_method = Kernel.instance_method(:method).bind_call(owner_receiver, method)
|
|
118
121
|
end
|
|
119
122
|
super_level.times do |s|
|
|
120
123
|
target_method = target_method.super_method if target_method
|
data/lib/irb/statement.rb
CHANGED
|
@@ -54,6 +54,27 @@ module IRB
|
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
+
class IncorrectAlias < Statement
|
|
58
|
+
attr_reader :message
|
|
59
|
+
|
|
60
|
+
def initialize(message)
|
|
61
|
+
@code = ""
|
|
62
|
+
@message = message
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def should_be_handled_by_debugger?
|
|
66
|
+
false
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def is_assignment?
|
|
70
|
+
false
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def suppresses_echo?
|
|
74
|
+
true
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
57
78
|
class Command < Statement
|
|
58
79
|
attr_reader :command_class, :arg
|
|
59
80
|
|
data/lib/irb/version.rb
CHANGED
data/lib/irb/workspace.rb
CHANGED
|
@@ -55,6 +55,15 @@ EOF
|
|
|
55
55
|
# Note that this will typically be IRB::TOPLEVEL_BINDING
|
|
56
56
|
# This is to avoid RubyGems' local variables (see issue #17623)
|
|
57
57
|
@binding = TOPLEVEL_BINDING.dup
|
|
58
|
+
|
|
59
|
+
when 5 # binding in Ruby::Box
|
|
60
|
+
unless defined?(Ruby::Box)
|
|
61
|
+
puts 'Context-mode 5 (binding in Ruby::Box) requires Ruby 4.0 or later.'
|
|
62
|
+
raise NameError, 'Ruby::Box not defined'
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
puts 'Context-mode 5 (binding in Ruby::Box) is experimental. It may be removed or changed without notice.'
|
|
66
|
+
@binding = Ruby::Box.new.eval('Kernel.binding')
|
|
58
67
|
end
|
|
59
68
|
end
|
|
60
69
|
|