irb 1.14.3 → 1.18.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 +11 -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 +251 -162
- data/lib/irb/color_printer.rb +10 -9
- data/lib/irb/command/base.rb +35 -0
- data/lib/irb/command/copy.rb +83 -0
- data/lib/irb/command/history.rb +1 -1
- data/lib/irb/command/internal_helpers.rb +6 -3
- data/lib/irb/command/ls.rb +6 -4
- data/lib/irb/completion.rb +69 -52
- data/lib/irb/context.rb +100 -64
- data/lib/irb/debug.rb +3 -3
- 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 +6 -1
- data/lib/irb/input-method.rb +158 -122
- 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/nesting_parser.rb +362 -213
- data/lib/irb/pager.rb +127 -6
- data/lib/irb/ruby-lex.rb +225 -299
- data/lib/irb/ruby_logo.aa +4 -0
- data/lib/irb/source_finder.rb +12 -18
- data/lib/irb/startup_message.rb +83 -0
- 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 +112 -927
- data/man/irb.1 +2 -0
- metadata +42 -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.
|
|
@@ -40,6 +42,14 @@ module IRB
|
|
|
40
42
|
# SIGTERM not supported (windows)
|
|
41
43
|
Process.kill("KILL", pid)
|
|
42
44
|
end
|
|
45
|
+
|
|
46
|
+
begin
|
|
47
|
+
# Wait for the pager process to terminate.
|
|
48
|
+
# Reading next input from Reline before the pager process is fully terminated
|
|
49
|
+
# may cause issues like raw/cooked mode not being controlled properly.
|
|
50
|
+
Process.waitpid(pid) if pid
|
|
51
|
+
rescue Errno::ECHILD, Errno::ESRCH
|
|
52
|
+
end
|
|
43
53
|
rescue Errno::ESRCH
|
|
44
54
|
# Pager process already terminated
|
|
45
55
|
end
|
|
@@ -47,12 +57,42 @@ module IRB
|
|
|
47
57
|
rescue Errno::EPIPE
|
|
48
58
|
end
|
|
49
59
|
|
|
50
|
-
private
|
|
51
|
-
|
|
52
60
|
def should_page?
|
|
53
61
|
IRB.conf[:USE_PAGER] && STDIN.tty? && (ENV.key?("TERM") && ENV["TERM"] != "dumb")
|
|
54
62
|
end
|
|
55
63
|
|
|
64
|
+
def page_with_preview(width, height, formatter_proc)
|
|
65
|
+
overflow_callback = ->(lines) do
|
|
66
|
+
modified_output = formatter_proc.call(lines.join, true)
|
|
67
|
+
content, = take_first_page(width, [height - 2, 0].max) {|o| o.write modified_output }
|
|
68
|
+
content = content.chomp
|
|
69
|
+
content = "#{content}\e[0m" if Color.colorable?
|
|
70
|
+
$stdout.puts content
|
|
71
|
+
$stdout.puts 'Preparing full inspection value...'
|
|
72
|
+
end
|
|
73
|
+
out = PageOverflowIO.new(width, height, overflow_callback, delay: 0.1)
|
|
74
|
+
yield out
|
|
75
|
+
content = formatter_proc.call(out.string, out.multipage?)
|
|
76
|
+
if out.multipage?
|
|
77
|
+
page(retain_content: true) do |io|
|
|
78
|
+
io.puts content
|
|
79
|
+
end
|
|
80
|
+
else
|
|
81
|
+
$stdout.puts content
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def take_first_page(width, height)
|
|
86
|
+
overflow_callback = proc do |lines|
|
|
87
|
+
return lines.join, true
|
|
88
|
+
end
|
|
89
|
+
out = Pager::PageOverflowIO.new(width, height, overflow_callback)
|
|
90
|
+
yield out
|
|
91
|
+
[out.string, false]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
56
96
|
def content_exceeds_screen_height?(content)
|
|
57
97
|
screen_height, screen_width = begin
|
|
58
98
|
Reline.get_screen_size
|
|
@@ -62,10 +102,10 @@ module IRB
|
|
|
62
102
|
|
|
63
103
|
pageable_height = screen_height - 3 # leave some space for previous and the current prompt
|
|
64
104
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
105
|
+
return true if content.lines.size > pageable_height
|
|
106
|
+
|
|
107
|
+
_, overflow = take_first_page(screen_width, pageable_height) {|out| out.write content }
|
|
108
|
+
overflow
|
|
69
109
|
end
|
|
70
110
|
|
|
71
111
|
def setup_pager(retain_content:)
|
|
@@ -96,5 +136,86 @@ module IRB
|
|
|
96
136
|
nil
|
|
97
137
|
end
|
|
98
138
|
end
|
|
139
|
+
|
|
140
|
+
# Writable IO that has page overflow callback
|
|
141
|
+
class PageOverflowIO
|
|
142
|
+
attr_reader :string, :first_page_lines
|
|
143
|
+
|
|
144
|
+
# Maximum size of a single cell in terminal
|
|
145
|
+
# Assumed worst case: "\e[1;3;4;9;38;2;255;128;128;48;2;128;128;255mA\e[0m"
|
|
146
|
+
# bold, italic, underline, crossed_out, RGB forgound, RGB background
|
|
147
|
+
MAX_CHAR_PER_CELL = 50
|
|
148
|
+
|
|
149
|
+
def initialize(width, height, overflow_callback, delay: nil)
|
|
150
|
+
@lines = []
|
|
151
|
+
@first_page_lines = nil
|
|
152
|
+
@width = width
|
|
153
|
+
@height = height
|
|
154
|
+
@buffer = +''
|
|
155
|
+
@overflow_callback = overflow_callback
|
|
156
|
+
@col = 0
|
|
157
|
+
@string = +''
|
|
158
|
+
@multipage = false
|
|
159
|
+
@delay_until = (Time.now + delay if delay)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def puts(text = '')
|
|
163
|
+
text = text.to_s unless text.is_a?(String)
|
|
164
|
+
write(text)
|
|
165
|
+
write("\n") unless text.end_with?("\n")
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def write(text)
|
|
169
|
+
text = text.to_s unless text.is_a?(String)
|
|
170
|
+
@string << text
|
|
171
|
+
if @multipage
|
|
172
|
+
if @delay_until && Time.now > @delay_until
|
|
173
|
+
@overflow_callback.call(@first_page_lines)
|
|
174
|
+
@delay_until = nil
|
|
175
|
+
end
|
|
176
|
+
return
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
overflow_size = (@width * (@height - @lines.size) + @width - @col) * MAX_CHAR_PER_CELL
|
|
180
|
+
if text.size >= overflow_size
|
|
181
|
+
text = text[0, overflow_size]
|
|
182
|
+
overflow = true
|
|
183
|
+
end
|
|
184
|
+
@buffer << text
|
|
185
|
+
@col += Reline::Unicode.calculate_width(text, true)
|
|
186
|
+
if text.include?("\n") || @col >= @width
|
|
187
|
+
@buffer.lines.each do |line|
|
|
188
|
+
wrapped_lines = Reline::Unicode.split_by_width(line.chomp, @width).first.compact
|
|
189
|
+
wrapped_lines.pop if wrapped_lines.last == ''
|
|
190
|
+
@lines.concat(wrapped_lines)
|
|
191
|
+
if line.end_with?("\n")
|
|
192
|
+
if @lines.empty? || @lines.last.end_with?("\n")
|
|
193
|
+
@lines << "\n"
|
|
194
|
+
else
|
|
195
|
+
@lines[-1] += "\n"
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
@buffer.clear
|
|
200
|
+
@buffer << @lines.pop if !@lines.empty? && !@lines.last.end_with?("\n")
|
|
201
|
+
@col = Reline::Unicode.calculate_width(@buffer, true)
|
|
202
|
+
end
|
|
203
|
+
if overflow || @lines.size > @height || (@lines.size == @height && @col > 0)
|
|
204
|
+
@first_page_lines = @lines.take(@height)
|
|
205
|
+
if !@delay_until || Time.now > @delay_until
|
|
206
|
+
@overflow_callback.call(@first_page_lines)
|
|
207
|
+
@delay_until = nil
|
|
208
|
+
end
|
|
209
|
+
@multipage = true
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def multipage?
|
|
214
|
+
@multipage
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
alias print write
|
|
218
|
+
alias << write
|
|
219
|
+
end
|
|
99
220
|
end
|
|
100
221
|
end
|