Switch to tracking linewrap on the last cell in a line
This allows us to have newline not affect the wrap status of a line. Now a lines wrapping status is changed only when the last cell in the line is changed. This actually matches the behavior of many other terminal emulators so is probably a good thing from a ecosystem compatibility perspective. The fish shell expects this weird behavior of newline not changing wrapping status, for unknown reasons, which is the actual motivation for doing all this work. Fixes #5766
This commit is contained in:
@@ -20,11 +20,10 @@ from . import BaseTest, filled_cursor, filled_history_buf, filled_line_buf
|
||||
def create_lbuf(*lines):
|
||||
maxw = max(map(len, lines))
|
||||
ans = LineBuf(len(lines), maxw)
|
||||
prev_full_length = False
|
||||
for i, l0 in enumerate(lines):
|
||||
ans.line(i).set_text(l0, 0, len(l0), C())
|
||||
ans.set_continued(i, prev_full_length)
|
||||
prev_full_length = len(l0) == maxw
|
||||
if i > 0:
|
||||
ans.set_continued(i, len(lines[i-1]) == maxw)
|
||||
return ans
|
||||
|
||||
|
||||
@@ -73,9 +72,9 @@ class TestDataTypes(BaseTest):
|
||||
self.assertFalse(c.reverse)
|
||||
self.assertTrue(c.bold)
|
||||
self.assertFalse(old.is_continued(0))
|
||||
old.set_continued(0, True)
|
||||
self.assertTrue(old.is_continued(0))
|
||||
self.assertFalse(old.is_continued(1))
|
||||
old.set_continued(1, True)
|
||||
self.assertTrue(old.is_continued(1))
|
||||
self.assertFalse(old.is_continued(0))
|
||||
|
||||
lb = filled_line_buf(5, 5, filled_cursor())
|
||||
lb2 = LineBuf(5, 5)
|
||||
@@ -518,7 +517,7 @@ class TestDataTypes(BaseTest):
|
||||
self.ae(l2.as_ansi(), '\x1b[1;2;3;7;9;34;48:2:1:2:3;58:5:5m' '1'
|
||||
'\x1b[22;23;27;29;39;49;59m' '0000')
|
||||
lb = filled_line_buf()
|
||||
for i in range(lb.ynum):
|
||||
for i in range(1, lb.ynum + 1):
|
||||
lb.set_continued(i, True)
|
||||
a = []
|
||||
lb.as_ansi(a.append)
|
||||
|
||||
@@ -210,22 +210,23 @@ class TestScreen(BaseTest):
|
||||
s.reset_dirty()
|
||||
s.cursor.x, s.cursor.y = 2, 1
|
||||
s.cursor.bold = True
|
||||
self.ae(continuations(s), (True, True, True, True, False))
|
||||
|
||||
def all_lines(s):
|
||||
return tuple(str(s.line(i)) for i in range(s.lines))
|
||||
|
||||
def continuations(s):
|
||||
return tuple(s.line(i).is_continued() for i in range(s.lines))
|
||||
return tuple(s.line(i).last_char_has_wrapped_flag() for i in range(s.lines))
|
||||
|
||||
init()
|
||||
s.erase_in_display(0)
|
||||
self.ae(all_lines(s), ('12345', '12', '', '', ''))
|
||||
self.ae(continuations(s), (False, True, False, False, False))
|
||||
self.ae(continuations(s), (True, False, False, False, False))
|
||||
|
||||
init()
|
||||
s.erase_in_display(1)
|
||||
self.ae(all_lines(s), ('', ' 45', '12345', '12345', '12345'))
|
||||
self.ae(continuations(s), (False, False, True, True, True))
|
||||
self.ae(continuations(s), (False, True, True, True, False))
|
||||
|
||||
init()
|
||||
s.erase_in_display(2)
|
||||
@@ -547,16 +548,20 @@ class TestScreen(BaseTest):
|
||||
s.draw(str(i) * s.columns)
|
||||
s.start_selection(0, 0)
|
||||
s.update_selection(4, 4)
|
||||
expected = ('55555', '\n66666', '\n77777', '\n88888', '\n99999')
|
||||
self.ae(s.text_for_selection(), expected)
|
||||
|
||||
def ts(*args):
|
||||
return ''.join(s.text_for_selection(*args))
|
||||
|
||||
expected = ''.join(('55555', '\n66666', '\n77777', '\n88888', '\n99999'))
|
||||
self.ae(ts(), expected)
|
||||
s.scroll(2, True)
|
||||
self.ae(s.text_for_selection(), expected)
|
||||
self.ae(ts(), expected)
|
||||
s.reset()
|
||||
s.draw('ab cd')
|
||||
s.start_selection(0, 0)
|
||||
s.update_selection(1, 3)
|
||||
self.ae(s.text_for_selection(), ('ab ', 'cd'))
|
||||
self.ae(s.text_for_selection(False, True), ('ab', 'cd'))
|
||||
self.ae(ts(), ''.join(('ab ', 'cd')))
|
||||
self.ae(ts(False, True), ''.join(('ab', 'cd')))
|
||||
s.reset()
|
||||
s.draw('ab cd')
|
||||
s.start_selection(0, 0)
|
||||
@@ -630,6 +635,22 @@ class TestScreen(BaseTest):
|
||||
s.draw('bcdef')
|
||||
self.ae(as_text(s, True), '\x1b[ma\x1b]8;;moo\x1b\\bcde\x1b[mf\n\n\n\x1b]8;;\x1b\\')
|
||||
|
||||
def test_wrapping_serialization(self):
|
||||
from kitty.window import as_text
|
||||
s = self.create_screen(cols=2, lines=2, scrollback=2, options={'scrollback_pager_history_size': 128})
|
||||
s.draw('aabbccddeeff')
|
||||
self.ae(as_text(s, add_history=True), 'aabbccddeeff')
|
||||
self.assertNotIn('\n', as_text(s, add_history=True, as_ansi=True))
|
||||
s = self.create_screen(cols=2, lines=2, scrollback=2, options={'scrollback_pager_history_size': 128})
|
||||
s.draw('1'), s.carriage_return(), s.linefeed()
|
||||
s.draw('2'), s.carriage_return(), s.linefeed()
|
||||
s.draw('3'), s.carriage_return(), s.linefeed()
|
||||
s.draw('4'), s.carriage_return(), s.linefeed()
|
||||
s.draw('5'), s.carriage_return(), s.linefeed()
|
||||
s.draw('6'), s.carriage_return(), s.linefeed()
|
||||
s.draw('7')
|
||||
self.ae(as_text(s, add_history=True), '1\n2\n3\n4\n5\n6\n7')
|
||||
|
||||
def test_pagerhist(self):
|
||||
hsz = 8
|
||||
s = self.create_screen(cols=2, lines=2, scrollback=2, options={'scrollback_pager_history_size': hsz})
|
||||
@@ -666,17 +687,17 @@ class TestScreen(BaseTest):
|
||||
s = self.create_screen(options={'scrollback_pager_history_size': 2048})
|
||||
text = '\x1b[msoft\r\x1b[mbreak\nnext😼cat'
|
||||
w(text)
|
||||
self.ae(contents(), text + '\n')
|
||||
self.ae(contents(), text)
|
||||
s.historybuf.pagerhist_rewrap(2)
|
||||
self.ae(contents(), '\x1b[mso\rft\x1b[m\rbr\rea\rk\nne\rxt\r😼\rca\rt\n')
|
||||
self.ae(contents(), '\x1b[mso\rft\x1b[m\rbr\rea\rk\nne\rxt\r😼\rca\rt')
|
||||
|
||||
s = self.create_screen(options={'scrollback_pager_history_size': 8})
|
||||
w('😼')
|
||||
self.ae(contents(), '😼\n')
|
||||
self.ae(contents(), '😼')
|
||||
w('abcd')
|
||||
self.ae(contents(), '😼abcd\n')
|
||||
self.ae(contents(), '😼abcd')
|
||||
w('e')
|
||||
self.ae(contents(), 'abcde\n')
|
||||
self.ae(contents(), 'abcde')
|
||||
|
||||
def test_user_marking(self):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user