Skip to content

Commit a139562

Browse files
authored
Fix pager preview with escape sequence and newlines (#1069)
1 parent d3531d8 commit a139562

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

lib/irb/pager.rb

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,13 @@ def initialize(width, height, overflow_callback, delay: nil)
152152
end
153153

154154
def puts(text = '')
155+
text = text.to_s unless text.is_a?(String)
155156
write(text)
156157
write("\n") unless text.end_with?("\n")
157158
end
158159

159160
def write(text)
161+
text = text.to_s unless text.is_a?(String)
160162
@string << text
161163
if @multipage
162164
if @delay_until && Time.now > @delay_until
@@ -171,23 +173,24 @@ def write(text)
171173
text = text[0, overflow_size]
172174
overflow = true
173175
end
174-
175176
@buffer << text
176-
@col += Reline::Unicode.calculate_width(text)
177+
@col += Reline::Unicode.calculate_width(text, true)
177178
if text.include?("\n") || @col >= @width
178179
@buffer.lines.each do |line|
179180
wrapped_lines = Reline::Unicode.split_by_width(line.chomp, @width).first.compact
180181
wrapped_lines.pop if wrapped_lines.last == ''
181182
@lines.concat(wrapped_lines)
182-
if @lines.empty?
183-
@lines << "\n"
184-
elsif line.end_with?("\n")
185-
@lines[-1] += "\n"
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
186189
end
187190
end
188191
@buffer.clear
189192
@buffer << @lines.pop unless @lines.last.end_with?("\n")
190-
@col = Reline::Unicode.calculate_width(@buffer)
193+
@col = Reline::Unicode.calculate_width(@buffer, true)
191194
end
192195
if overflow || @lines.size > @height || (@lines.size == @height && @col > 0)
193196
@first_page_lines = @lines.take(@height)

test/irb/test_pager.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,21 @@ module TestIRB
77
class PagerTest < TestCase
88
def test_take_first_page
99
assert_equal ['a' * 40, true], IRB::Pager.take_first_page(10, 4) {|io| io.puts 'a' * 41; raise 'should not reach here' }
10+
assert_equal ["a\nb\na\nb\n", true], IRB::Pager.take_first_page(10, 4) {|io| 10.times { io.puts "a\nb\n" } }
11+
assert_equal ["a\n\n\na\n", true], IRB::Pager.take_first_page(10, 4) {|io| 10.times { io.puts "a\n\n\n" } }
12+
assert_equal ["11\n" * 4, true], IRB::Pager.take_first_page(10, 4) {|io| 10.times { io.write 1; io.puts 1 } }
13+
assert_equal ["\n" * 4, true], IRB::Pager.take_first_page(10, 4) {|io| 10.times { io.write nil; io.puts nil } }
1014
assert_equal ['a' * 39, false], IRB::Pager.take_first_page(10, 4) {|io| io.write 'a' * 39 }
1115
assert_equal ['a' * 39 + 'b', false], IRB::Pager.take_first_page(10, 4) {|io| io.write 'a' * 39 + 'b' }
1216
assert_equal ['a' * 39 + 'b', true], IRB::Pager.take_first_page(10, 4) {|io| io.write 'a' * 39 + 'bc' }
1317
assert_equal ["a\nb\nc\nd\n", false], IRB::Pager.take_first_page(10, 4) {|io| io.write "a\nb\nc\nd\n" }
1418
assert_equal ["a\nb\nc\nd\n", true], IRB::Pager.take_first_page(10, 4) {|io| io.write "a\nb\nc\nd\ne" }
1519
assert_equal ['a' * 15 + "\n" + 'b' * 20, true], IRB::Pager.take_first_page(10, 4) {|io| io.puts 'a' * 15; io.puts 'b' * 30 }
16-
assert_equal ["\e[31mA\e[0m" * 10 + 'x' * 30, true], IRB::Pager.take_first_page(10, 4) {|io| io.puts "\e[31mA\e[0m" * 10 + 'x' * 31; }
20+
assert_equal ["\e[31mA\e[0m" * 10 + 'x' * 30, true], IRB::Pager.take_first_page(10, 4) {|io| io.puts "\e[31mA\e[0m" * 10 + 'x' * 31 }
21+
text, overflow = IRB::Pager.take_first_page(10, 4) {|io| 41.times { io.write "\e[31mA\e[0m" } }
22+
assert_equal ['A' * 40, true], [text.gsub(/\e\[\d+m/, ''), overflow]
23+
text, overflow = IRB::Pager.take_first_page(10, 4) {|io| 41.times { io.write "\e[31mAAA\e[0m" } }
24+
assert_equal ['A' * 40, true], [text.gsub(/\e\[\d+m/, ''), overflow]
1725
end
1826
end
1927

0 commit comments

Comments
 (0)