irb 1.14.3 → 1.15.3
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 +4 -0
- 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 +275 -0
- data/doc/EXTEND_IRB.md +122 -0
- data/doc/Index.md +705 -0
- 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 +95 -60
- 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/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/pager.rb +119 -6
- data/lib/irb/ruby-lex.rb +25 -0
- data/lib/irb/source_finder.rb +1 -1
- data/lib/irb/statement.rb +21 -0
- data/lib/irb/version.rb +2 -2
- 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/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
|
@@ -114,7 +114,7 @@ module IRB
|
|
|
114
114
|
when "owner"
|
|
115
115
|
target_method = owner_receiver.instance_method(method)
|
|
116
116
|
when "receiver"
|
|
117
|
-
target_method =
|
|
117
|
+
target_method = Kernel.instance_method(:method).bind_call(owner_receiver, method)
|
|
118
118
|
end
|
|
119
119
|
super_level.times do |s|
|
|
120
120
|
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
|
|