2019-05-20 13:38:06 +03:00
|
|
|
#!/usr/bin/env python3
|
2016-10-18 08:34:30 +03:00
|
|
|
# vim:fileencoding=utf-8
|
|
|
|
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
|
|
|
2017-01-10 11:22:15 +03:00
|
|
|
from . import BaseTest
|
2016-11-30 12:28:34 +03:00
|
|
|
from kitty.fast_data_types import DECAWM, IRM, Cursor, DECCOLM, DECOM
|
2020-01-12 18:31:28 +03:00
|
|
|
from kitty.marks import marker_from_regex, marker_from_function
|
2016-10-18 08:34:30 +03:00
|
|
|
|
|
|
|
|
|
|
|
class TestScreen(BaseTest):
|
|
|
|
|
2016-11-08 07:23:51 +03:00
|
|
|
def test_draw_fast(self):
|
2016-11-13 19:53:28 +03:00
|
|
|
s = self.create_screen()
|
2016-11-13 11:40:57 +03:00
|
|
|
|
2016-10-18 08:34:30 +03:00
|
|
|
# Test in line-wrap, non-insert mode
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('a' * 5)
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(0)), 'a' * 5)
|
2016-10-18 08:34:30 +03:00
|
|
|
self.ae(s.cursor.x, 5), self.ae(s.cursor.y, 0)
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('b' * 7)
|
2016-11-08 07:23:51 +03:00
|
|
|
self.assertTrue(s.linebuf.is_continued(1))
|
|
|
|
self.assertTrue(s.linebuf.is_continued(2))
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(0)), 'a' * 5)
|
|
|
|
self.ae(str(s.line(1)), 'b' * 5)
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(str(s.line(2)), 'b' * 2)
|
2016-10-18 08:34:30 +03:00
|
|
|
self.ae(s.cursor.x, 2), self.ae(s.cursor.y, 2)
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('c' * 15)
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(0)), 'b' * 5)
|
|
|
|
self.ae(str(s.line(1)), 'bbccc')
|
2016-10-18 08:34:30 +03:00
|
|
|
|
|
|
|
# Now test without line-wrap
|
2016-11-11 16:05:26 +03:00
|
|
|
s.reset(), s.reset_dirty()
|
2016-11-13 11:40:57 +03:00
|
|
|
s.reset_mode(DECAWM)
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('0123456789')
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(0)), '01239')
|
2016-10-18 08:34:30 +03:00
|
|
|
self.ae(s.cursor.x, 5), self.ae(s.cursor.y, 0)
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('ab')
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(0)), '0123b')
|
2016-10-18 08:34:30 +03:00
|
|
|
self.ae(s.cursor.x, 5), self.ae(s.cursor.y, 0)
|
|
|
|
|
|
|
|
# Now test in insert mode
|
2016-11-11 16:05:26 +03:00
|
|
|
s.reset(), s.reset_dirty()
|
2016-11-13 11:40:57 +03:00
|
|
|
s.set_mode(IRM)
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('12345' * 5)
|
2016-10-18 08:34:30 +03:00
|
|
|
s.cursor_back(5)
|
|
|
|
self.ae(s.cursor.x, 0), self.ae(s.cursor.y, 4)
|
2016-11-11 16:05:26 +03:00
|
|
|
s.reset_dirty()
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('ab')
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(4)), 'ab123')
|
2016-10-18 08:34:30 +03:00
|
|
|
self.ae((s.cursor.x, s.cursor.y), (2, 4))
|
2016-10-18 18:00:18 +03:00
|
|
|
|
2016-11-08 07:23:51 +03:00
|
|
|
def test_draw_char(self):
|
2016-10-18 18:00:18 +03:00
|
|
|
# Test in line-wrap, non-insert mode
|
2016-11-13 19:53:28 +03:00
|
|
|
s = self.create_screen()
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('ココx')
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(0)), 'ココx')
|
|
|
|
self.ae(tuple(map(s.line(0).width, range(5))), (2, 0, 2, 0, 1))
|
2016-10-18 18:00:18 +03:00
|
|
|
self.ae(s.cursor.x, 5), self.ae(s.cursor.y, 0)
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('ニチハ')
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(0)), 'ココx')
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(str(s.line(1)), 'ニチ')
|
|
|
|
self.ae(str(s.line(2)), 'ハ')
|
2016-10-18 18:00:18 +03:00
|
|
|
self.ae(s.cursor.x, 2), self.ae(s.cursor.y, 2)
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('Ƶ̧\u0308')
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(str(s.line(2)), 'ハƵ̧\u0308')
|
2016-10-18 18:00:18 +03:00
|
|
|
self.ae(s.cursor.x, 3), self.ae(s.cursor.y, 2)
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('xy'), s.draw('\u0306')
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(2)), 'ハƵ̧\u0308xy\u0306')
|
2016-10-18 18:00:18 +03:00
|
|
|
self.ae(s.cursor.x, 5), self.ae(s.cursor.y, 2)
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('c' * 15)
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(str(s.line(0)), 'ニチ')
|
2016-10-18 18:00:18 +03:00
|
|
|
|
|
|
|
# Now test without line-wrap
|
2016-11-11 16:05:26 +03:00
|
|
|
s.reset(), s.reset_dirty()
|
2016-11-13 11:40:57 +03:00
|
|
|
s.reset_mode(DECAWM)
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('0\u030612345\u03066789\u0306')
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(0)), '0\u03061239\u0306')
|
2016-10-18 18:00:18 +03:00
|
|
|
self.ae(s.cursor.x, 5), self.ae(s.cursor.y, 0)
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('ab\u0306')
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(0)), '0\u0306123b\u0306')
|
2016-10-18 18:00:18 +03:00
|
|
|
self.ae(s.cursor.x, 5), self.ae(s.cursor.y, 0)
|
|
|
|
|
|
|
|
# Now test in insert mode
|
2016-11-11 16:05:26 +03:00
|
|
|
s.reset(), s.reset_dirty()
|
2016-11-13 11:40:57 +03:00
|
|
|
s.set_mode(IRM)
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('1\u03062345' * 5)
|
2016-10-18 18:00:18 +03:00
|
|
|
s.cursor_back(5)
|
|
|
|
self.ae(s.cursor.x, 0), self.ae(s.cursor.y, 4)
|
2016-11-11 16:05:26 +03:00
|
|
|
s.reset_dirty()
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('a\u0306b')
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(4)), 'a\u0306b1\u030623')
|
2016-10-18 18:00:18 +03:00
|
|
|
self.ae((s.cursor.x, s.cursor.y), (2, 4))
|
2016-10-19 08:55:55 +03:00
|
|
|
|
2018-08-04 07:36:25 +03:00
|
|
|
def test_emoji_skin_tone_modifiers(self):
|
|
|
|
s = self.create_screen()
|
|
|
|
q = chr(0x1f469) + chr(0x1f3fd)
|
|
|
|
s.draw(q)
|
|
|
|
self.ae(str(s.line(0)), q)
|
|
|
|
self.ae(s.cursor.x, 2)
|
|
|
|
|
2018-08-04 15:59:45 +03:00
|
|
|
def test_zwj(self):
|
|
|
|
s = self.create_screen(cols=20)
|
|
|
|
q = '\U0001f468\u200d\U0001f469\u200d\U0001f467\u200d\U0001f466'
|
|
|
|
s.draw(q)
|
|
|
|
self.ae(q, str(s.line(0)))
|
|
|
|
self.ae(s.cursor.x, 8)
|
|
|
|
|
2016-11-08 07:23:51 +03:00
|
|
|
def test_char_manipulation(self):
|
2016-11-13 19:53:28 +03:00
|
|
|
s = self.create_screen()
|
2016-10-19 08:55:55 +03:00
|
|
|
|
|
|
|
def init():
|
2016-11-11 16:05:26 +03:00
|
|
|
s.reset(), s.reset_dirty()
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('abcde')
|
2016-10-19 08:55:55 +03:00
|
|
|
s.cursor.bold = True
|
|
|
|
s.cursor_back(4)
|
2016-11-11 16:05:26 +03:00
|
|
|
s.reset_dirty()
|
2016-10-19 08:55:55 +03:00
|
|
|
self.ae(s.cursor.x, 1)
|
|
|
|
|
|
|
|
init()
|
|
|
|
s.insert_characters(2)
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(0)), 'a bc')
|
|
|
|
self.assertTrue(s.line(0).cursor_from(1).bold)
|
2016-10-19 08:55:55 +03:00
|
|
|
s.cursor_back(1)
|
|
|
|
s.insert_characters(20)
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(str(s.line(0)), '')
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('xココ')
|
2016-10-19 08:55:55 +03:00
|
|
|
s.cursor_back(5)
|
2016-11-11 16:05:26 +03:00
|
|
|
s.reset_dirty()
|
2016-10-19 08:55:55 +03:00
|
|
|
s.insert_characters(1)
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(str(s.line(0)), ' xコ')
|
2016-11-13 14:21:14 +03:00
|
|
|
c = Cursor()
|
2016-11-13 14:22:59 +03:00
|
|
|
c.italic = True
|
2016-11-13 14:21:14 +03:00
|
|
|
s.line(0).apply_cursor(c, 0, 5)
|
|
|
|
self.ae(s.line(0).width(2), 2)
|
2016-11-13 14:22:59 +03:00
|
|
|
self.assertTrue(s.line(0).cursor_from(2).italic)
|
|
|
|
self.assertFalse(s.line(0).cursor_from(2).bold)
|
2016-10-19 08:55:55 +03:00
|
|
|
|
|
|
|
init()
|
|
|
|
s.delete_characters(2)
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(str(s.line(0)), 'ade')
|
2016-10-20 21:35:50 +03:00
|
|
|
self.assertTrue(s.line(0).cursor_from(4).bold)
|
|
|
|
self.assertFalse(s.line(0).cursor_from(2).bold)
|
2016-10-19 08:55:55 +03:00
|
|
|
|
|
|
|
init()
|
|
|
|
s.erase_characters(2)
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(0)), 'a de')
|
|
|
|
self.assertTrue(s.line(0).cursor_from(1).bold)
|
|
|
|
self.assertFalse(s.line(0).cursor_from(4).bold)
|
2016-10-19 08:55:55 +03:00
|
|
|
s.erase_characters(20)
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(str(s.line(0)), 'a')
|
2016-10-19 08:55:55 +03:00
|
|
|
|
|
|
|
init()
|
|
|
|
s.erase_in_line()
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(str(s.line(0)), 'a')
|
2016-10-20 21:35:50 +03:00
|
|
|
self.assertTrue(s.line(0).cursor_from(1).bold)
|
|
|
|
self.assertFalse(s.line(0).cursor_from(0).bold)
|
2016-10-19 08:55:55 +03:00
|
|
|
init()
|
|
|
|
s.erase_in_line(1)
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae(str(s.line(0)), ' cde')
|
2016-10-19 08:55:55 +03:00
|
|
|
init()
|
|
|
|
s.erase_in_line(2)
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(str(s.line(0)), '')
|
2016-10-19 08:55:55 +03:00
|
|
|
init()
|
2016-11-13 14:21:14 +03:00
|
|
|
s.erase_in_line(2, True)
|
2016-10-20 21:35:50 +03:00
|
|
|
self.ae((False, False, False, False, False), tuple(map(lambda i: s.line(0).cursor_from(i).bold, range(5))))
|
2016-10-19 11:19:27 +03:00
|
|
|
|
2016-11-08 07:23:51 +03:00
|
|
|
def test_erase_in_screen(self):
|
2016-11-13 19:53:28 +03:00
|
|
|
s = self.create_screen()
|
2016-10-19 11:19:27 +03:00
|
|
|
|
|
|
|
def init():
|
|
|
|
s.reset()
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('12345' * 5)
|
2016-11-11 16:05:26 +03:00
|
|
|
s.reset_dirty()
|
2016-10-19 11:19:27 +03:00
|
|
|
s.cursor.x, s.cursor.y = 2, 1
|
|
|
|
s.cursor.bold = True
|
|
|
|
|
2016-11-13 14:31:45 +03:00
|
|
|
def all_lines(s):
|
|
|
|
return tuple(str(s.line(i)) for i in range(s.lines))
|
|
|
|
|
2016-10-19 11:19:27 +03:00
|
|
|
init()
|
|
|
|
s.erase_in_display()
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(all_lines(s), ('12345', '12', '', '', ''))
|
2016-10-19 11:19:27 +03:00
|
|
|
|
|
|
|
init()
|
|
|
|
s.erase_in_display(1)
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(all_lines(s), ('', ' 45', '12345', '12345', '12345'))
|
2016-10-19 11:19:27 +03:00
|
|
|
|
|
|
|
init()
|
|
|
|
s.erase_in_display(2)
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(all_lines(s), ('', '', '', '', ''))
|
2016-10-20 21:35:50 +03:00
|
|
|
self.assertTrue(s.line(0).cursor_from(1).bold)
|
2016-10-19 11:19:27 +03:00
|
|
|
init()
|
2016-11-13 14:31:45 +03:00
|
|
|
s.erase_in_display(2, True)
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(all_lines(s), ('', '', '', '', ''))
|
2016-10-20 21:35:50 +03:00
|
|
|
self.assertFalse(s.line(0).cursor_from(1).bold)
|
2016-10-19 17:45:07 +03:00
|
|
|
|
2016-11-08 07:23:51 +03:00
|
|
|
def test_cursor_movement(self):
|
2016-11-11 16:05:26 +03:00
|
|
|
s = self.create_screen()
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('12345' * 5)
|
2016-11-11 16:05:26 +03:00
|
|
|
s.reset_dirty()
|
2016-10-19 17:45:07 +03:00
|
|
|
s.cursor_up(2)
|
|
|
|
self.ae((s.cursor.x, s.cursor.y), (4, 2))
|
|
|
|
s.cursor_up1()
|
|
|
|
self.ae((s.cursor.x, s.cursor.y), (0, 1))
|
|
|
|
s.cursor_forward(3)
|
|
|
|
self.ae((s.cursor.x, s.cursor.y), (3, 1))
|
|
|
|
s.cursor_back()
|
|
|
|
self.ae((s.cursor.x, s.cursor.y), (2, 1))
|
|
|
|
s.cursor_down()
|
|
|
|
self.ae((s.cursor.x, s.cursor.y), (2, 2))
|
|
|
|
s.cursor_down1(5)
|
|
|
|
self.ae((s.cursor.x, s.cursor.y), (0, 4))
|
2016-11-10 10:24:38 +03:00
|
|
|
|
2016-11-11 16:05:26 +03:00
|
|
|
s = self.create_screen()
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('12345' * 5)
|
2016-11-10 10:24:38 +03:00
|
|
|
s.index()
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(str(s.line(4)), '')
|
2016-11-10 10:25:36 +03:00
|
|
|
for i in range(4):
|
|
|
|
self.ae(str(s.line(i)), '12345')
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw('12345' * 5)
|
2016-11-10 10:24:38 +03:00
|
|
|
s.cursor_up(5)
|
|
|
|
s.reverse_index()
|
2017-09-09 07:55:03 +03:00
|
|
|
self.ae(str(s.line(0)), '')
|
2016-11-10 10:25:36 +03:00
|
|
|
for i in range(1, 5):
|
|
|
|
self.ae(str(s.line(i)), '12345')
|
2016-11-21 06:37:52 +03:00
|
|
|
|
2018-09-07 07:38:25 +03:00
|
|
|
def test_backspace_wide_characters(self):
|
|
|
|
s = self.create_screen()
|
|
|
|
s.draw('⛅')
|
|
|
|
self.ae(s.cursor.x, 2)
|
|
|
|
s.backspace()
|
|
|
|
s.draw(' ')
|
|
|
|
s.backspace()
|
2018-09-09 11:32:46 +03:00
|
|
|
self.ae(s.cursor.x, 1)
|
2018-09-07 07:38:25 +03:00
|
|
|
|
2016-11-21 06:37:52 +03:00
|
|
|
def test_resize(self):
|
|
|
|
s = self.create_screen(scrollback=6)
|
2016-11-23 17:56:29 +03:00
|
|
|
s.draw(''.join([str(i) * s.columns for i in range(s.lines)]))
|
2016-11-21 06:37:52 +03:00
|
|
|
s.resize(3, 10)
|
2018-02-02 09:35:52 +03:00
|
|
|
self.ae(str(s.line(0)), '0'*5 + '1'*5)
|
|
|
|
self.ae(str(s.line(1)), '2'*5 + '3'*5)
|
|
|
|
self.ae(str(s.line(2)), '4'*5)
|
2016-11-21 06:37:52 +03:00
|
|
|
s.resize(5, 1)
|
|
|
|
self.ae(str(s.line(0)), '4')
|
|
|
|
hb = s.historybuf
|
2018-02-02 09:35:52 +03:00
|
|
|
self.ae(str(hb), '3\n3\n3\n3\n3\n2')
|
2017-09-20 08:29:31 +03:00
|
|
|
s = self.create_screen(scrollback=20)
|
|
|
|
s.draw(''.join(str(i) * s.columns for i in range(s.lines*2)))
|
|
|
|
self.ae(str(s.linebuf), '55555\n66666\n77777\n88888\n99999')
|
2016-12-12 08:28:18 +03:00
|
|
|
s.resize(5, 2)
|
2017-11-13 17:16:20 +03:00
|
|
|
self.ae(str(s.linebuf), '88\n88\n99\n99\n9')
|
2017-09-20 08:29:31 +03:00
|
|
|
|
|
|
|
def test_cursor_after_resize(self):
|
2018-02-02 08:49:42 +03:00
|
|
|
|
|
|
|
def draw(text, end_line=True):
|
|
|
|
s.draw(text)
|
|
|
|
if end_line:
|
|
|
|
s.linefeed(), s.carriage_return()
|
|
|
|
|
2017-09-20 08:29:31 +03:00
|
|
|
s = self.create_screen()
|
2018-02-02 08:49:42 +03:00
|
|
|
draw('123'), draw('123')
|
2017-09-20 08:29:31 +03:00
|
|
|
y_before = s.cursor.y
|
|
|
|
s.resize(s.lines, s.columns-1)
|
|
|
|
self.ae(y_before, s.cursor.y)
|
2016-11-30 07:51:37 +03:00
|
|
|
|
2018-02-02 08:49:42 +03:00
|
|
|
s = self.create_screen(cols=5, lines=8)
|
|
|
|
draw('one')
|
|
|
|
draw('two three four five |||', end_line=False)
|
|
|
|
s.resize(s.lines + 2, s.columns + 2)
|
|
|
|
y = s.cursor.y
|
|
|
|
self.assertIn('|', str(s.line(y)))
|
|
|
|
|
2018-02-25 06:45:48 +03:00
|
|
|
s = self.create_screen()
|
|
|
|
draw('a')
|
|
|
|
x_before = s.cursor.x
|
|
|
|
s.resize(s.lines - 1, s.columns)
|
|
|
|
self.ae(x_before, s.cursor.x)
|
|
|
|
|
2016-11-30 07:51:37 +03:00
|
|
|
def test_tab_stops(self):
|
|
|
|
# Taken from vttest/main.c
|
|
|
|
s = self.create_screen(cols=80, lines=2)
|
|
|
|
s.cursor_position(1, 1)
|
|
|
|
s.clear_tab_stop(3)
|
|
|
|
for col in range(1, s.columns - 1, 3):
|
|
|
|
s.cursor_forward(3)
|
|
|
|
s.set_tab_stop()
|
|
|
|
s.cursor_position(1, 4)
|
|
|
|
for col in range(4, s.columns - 1, 6):
|
|
|
|
s.clear_tab_stop(0)
|
|
|
|
s.cursor_forward(6)
|
|
|
|
s.cursor_position(1, 7)
|
|
|
|
s.clear_tab_stop(2)
|
|
|
|
s.cursor_position(1, 1)
|
|
|
|
for col in range(1, s.columns - 1, 6):
|
|
|
|
s.tab()
|
|
|
|
s.draw('*')
|
|
|
|
s.cursor_position(2, 2)
|
2019-08-31 10:07:05 +03:00
|
|
|
self.ae(str(s.line(0)), '\t*'*13)
|
2016-11-30 12:28:34 +03:00
|
|
|
|
|
|
|
def test_margins(self):
|
|
|
|
# Taken from vttest/main.c
|
|
|
|
s = self.create_screen(cols=80, lines=24)
|
|
|
|
|
|
|
|
def nl():
|
|
|
|
s.carriage_return(), s.linefeed()
|
|
|
|
|
|
|
|
for deccolm in (False, True):
|
|
|
|
if deccolm:
|
|
|
|
s.resize(24, 132)
|
|
|
|
s.set_mode(DECCOLM)
|
|
|
|
else:
|
|
|
|
s.reset_mode(DECCOLM)
|
|
|
|
region = s.lines - 6
|
|
|
|
s.set_margins(3, region + 3)
|
|
|
|
s.set_mode(DECOM)
|
2016-11-30 12:42:00 +03:00
|
|
|
for i in range(26):
|
|
|
|
ch = chr(ord('A') + i)
|
2016-11-30 12:28:34 +03:00
|
|
|
which = i % 4
|
|
|
|
if which == 0:
|
|
|
|
s.cursor_position(region + 1, 1), s.draw(ch)
|
|
|
|
s.cursor_position(region + 1, s.columns), s.draw(ch.lower())
|
|
|
|
nl()
|
2016-11-30 12:42:00 +03:00
|
|
|
elif which == 1:
|
|
|
|
# Simple wrapping
|
|
|
|
s.cursor_position(region, s.columns), s.draw(chr(ord('A') + i - 1).lower() + ch)
|
|
|
|
# Backspace at right margin
|
|
|
|
s.cursor_position(region + 1, s.columns), s.draw(ch), s.backspace(), s.draw(ch.lower())
|
|
|
|
nl()
|
|
|
|
elif which == 2:
|
|
|
|
# Tab to right margin
|
|
|
|
s.cursor_position(region + 1, s.columns), s.draw(ch), s.backspace(), s.backspace(), s.tab(), s.tab(), s.draw(ch.lower())
|
|
|
|
s.cursor_position(region + 1, 2), s.backspace(), s.draw(ch), nl()
|
2016-11-30 12:28:34 +03:00
|
|
|
else:
|
|
|
|
s.cursor_position(region + 1, 1), nl()
|
|
|
|
s.cursor_position(region, 1), s.draw(ch)
|
|
|
|
s.cursor_position(region, s.columns), s.draw(ch.lower())
|
2020-05-12 20:24:08 +03:00
|
|
|
for ln in range(2, region + 2):
|
|
|
|
c = chr(ord('I') + ln - 2)
|
|
|
|
before = '\t' if ln % 4 == 0 else ' '
|
|
|
|
self.ae(c + ' ' * (s.columns - 3) + before + c.lower(), str(s.line(ln)))
|
2016-11-30 12:28:34 +03:00
|
|
|
s.reset_mode(DECOM)
|
2018-05-19 05:34:37 +03:00
|
|
|
# Test that moving cursor outside the margins works as expected
|
|
|
|
s = self.create_screen(10, 10)
|
2018-06-11 07:43:21 +03:00
|
|
|
s.set_margins(4, 6)
|
2018-05-19 05:34:37 +03:00
|
|
|
s.cursor_position(0, 0)
|
|
|
|
self.ae(s.cursor.y, 0)
|
|
|
|
nl()
|
|
|
|
self.ae(s.cursor.y, 1)
|
2018-06-11 07:43:21 +03:00
|
|
|
s.cursor.y = s.lines - 1
|
|
|
|
self.ae(s.cursor.y, 9)
|
|
|
|
s.reverse_index()
|
|
|
|
self.ae(s.cursor.y, 8)
|
2016-11-30 18:46:04 +03:00
|
|
|
|
|
|
|
def test_sgr(self):
|
|
|
|
s = self.create_screen()
|
|
|
|
s.select_graphic_rendition(0, 1, 37, 42)
|
|
|
|
s.draw('a')
|
|
|
|
c = s.line(0).cursor_from(0)
|
|
|
|
self.assertTrue(c.bold)
|
|
|
|
self.ae(c.bg, (2 << 8) | 1)
|
|
|
|
s.cursor_position(2, 1)
|
|
|
|
s.select_graphic_rendition(0, 35)
|
|
|
|
s.draw('b')
|
|
|
|
c = s.line(1).cursor_from(0)
|
|
|
|
self.ae(c.fg, (5 << 8) | 1)
|
|
|
|
self.ae(c.bg, 0)
|
2017-12-12 16:20:37 +03:00
|
|
|
s.cursor_position(2, 2)
|
|
|
|
s.select_graphic_rendition(38, 2, 99, 1, 2, 3)
|
|
|
|
s.draw('c')
|
|
|
|
c = s.line(1).cursor_from(1)
|
|
|
|
self.ae(c.fg, (1 << 24) | (2 << 16) | (3 << 8) | 2)
|
2017-01-04 07:54:00 +03:00
|
|
|
|
|
|
|
def test_cursor_hidden(self):
|
|
|
|
s = self.create_screen()
|
|
|
|
s.toggle_alt_screen()
|
|
|
|
s.cursor_visible = False
|
|
|
|
s.toggle_alt_screen()
|
|
|
|
self.assertFalse(s.cursor_visible)
|
2017-11-09 10:21:02 +03:00
|
|
|
|
|
|
|
def test_dirty_lines(self):
|
|
|
|
s = self.create_screen()
|
|
|
|
self.assertFalse(s.linebuf.dirty_lines())
|
|
|
|
s.draw('a' * (s.columns * 2))
|
|
|
|
self.ae(s.linebuf.dirty_lines(), [0, 1])
|
|
|
|
self.assertFalse(s.historybuf.dirty_lines())
|
|
|
|
while not s.historybuf.count:
|
|
|
|
s.draw('a' * (s.columns * 2))
|
|
|
|
self.ae(s.historybuf.dirty_lines(), list(range(s.historybuf.count)))
|
|
|
|
self.ae(s.linebuf.dirty_lines(), list(range(s.lines)))
|
|
|
|
s.cursor.x, s.cursor.y = 0, 1
|
|
|
|
s.insert_lines(2)
|
|
|
|
self.ae(s.linebuf.dirty_lines(), [0, 3, 4])
|
|
|
|
s.draw('a' * (s.columns * s.lines))
|
|
|
|
self.ae(s.linebuf.dirty_lines(), list(range(s.lines)))
|
|
|
|
s.cursor.x, s.cursor.y = 0, 1
|
|
|
|
s.delete_lines(2)
|
|
|
|
self.ae(s.linebuf.dirty_lines(), [0, 1, 2])
|
|
|
|
|
|
|
|
s = self.create_screen()
|
|
|
|
self.assertFalse(s.linebuf.dirty_lines())
|
|
|
|
s.erase_in_line(0, False)
|
|
|
|
self.ae(s.linebuf.dirty_lines(), [0])
|
|
|
|
s.index(), s.index()
|
|
|
|
s.erase_in_display(0, False)
|
|
|
|
self.ae(s.linebuf.dirty_lines(), [0, 2, 3, 4])
|
|
|
|
|
|
|
|
s = self.create_screen()
|
|
|
|
self.assertFalse(s.linebuf.dirty_lines())
|
|
|
|
s.insert_characters(2)
|
|
|
|
self.ae(s.linebuf.dirty_lines(), [0])
|
|
|
|
s.cursor.y = 1
|
|
|
|
s.delete_characters(2)
|
|
|
|
self.ae(s.linebuf.dirty_lines(), [0, 1])
|
|
|
|
s.cursor.y = 2
|
|
|
|
s.erase_characters(2)
|
|
|
|
self.ae(s.linebuf.dirty_lines(), [0, 1, 2])
|
2018-01-17 19:09:24 +03:00
|
|
|
|
|
|
|
def test_selection_as_text(self):
|
|
|
|
s = self.create_screen()
|
|
|
|
for i in range(2 * s.lines):
|
|
|
|
if i != 0:
|
|
|
|
s.carriage_return(), s.linefeed()
|
|
|
|
s.draw(str(i) * s.columns)
|
2020-02-23 06:54:20 +03:00
|
|
|
s.start_selection(0, 0)
|
2020-02-18 15:15:07 +03:00
|
|
|
s.update_selection(4, 4)
|
2018-01-17 19:09:24 +03:00
|
|
|
expected = ('55555', '\n66666', '\n77777', '\n88888', '\n99999')
|
|
|
|
self.ae(s.text_for_selection(), expected)
|
|
|
|
s.scroll(2, True)
|
|
|
|
self.ae(s.text_for_selection(), expected)
|
2018-02-14 16:05:32 +03:00
|
|
|
|
2019-05-13 17:48:41 +03:00
|
|
|
def test_variation_selectors(self):
|
|
|
|
s = self.create_screen()
|
|
|
|
s.draw('\U0001f610')
|
|
|
|
self.ae(s.cursor.x, 2)
|
|
|
|
s.carriage_return(), s.linefeed()
|
|
|
|
s.draw('\U0001f610\ufe0e')
|
|
|
|
self.ae(s.cursor.x, 1)
|
|
|
|
s.carriage_return(), s.linefeed()
|
|
|
|
s.draw('\u25b6')
|
|
|
|
self.ae(s.cursor.x, 1)
|
|
|
|
s.carriage_return(), s.linefeed()
|
|
|
|
s.draw('\u25b6\ufe0f')
|
|
|
|
self.ae(s.cursor.x, 2)
|
|
|
|
|
2018-02-14 16:05:32 +03:00
|
|
|
def test_serialize(self):
|
|
|
|
s = self.create_screen()
|
|
|
|
s.draw('ab' * s.columns)
|
|
|
|
s.carriage_return(), s.linefeed()
|
|
|
|
s.draw('c')
|
|
|
|
|
|
|
|
def as_text(as_ansi=False):
|
|
|
|
d = []
|
|
|
|
s.as_text(d.append, as_ansi)
|
|
|
|
return ''.join(d)
|
|
|
|
|
|
|
|
self.ae(as_text(), 'ababababab\nc\n\n')
|
2020-02-25 16:53:05 +03:00
|
|
|
self.ae(as_text(True), '\x1b[mababa\x1b[mbabab\n\x1b[mc\n\n')
|
2020-01-12 16:59:55 +03:00
|
|
|
|
|
|
|
def test_user_marking(self):
|
2020-04-12 10:58:21 +03:00
|
|
|
|
|
|
|
def cells(*a, y=0, mark=3):
|
|
|
|
return [(x, y, mark) for x in a]
|
|
|
|
|
2020-01-12 16:59:55 +03:00
|
|
|
s = self.create_screen()
|
|
|
|
s.draw('abaa')
|
2020-01-12 18:31:28 +03:00
|
|
|
s.carriage_return(), s.linefeed()
|
|
|
|
s.draw('xyxyx')
|
2020-01-13 09:27:19 +03:00
|
|
|
s.set_marker(marker_from_regex('a', 3))
|
2020-04-12 10:58:21 +03:00
|
|
|
self.ae(s.marked_cells(), cells(0, 2, 3))
|
2020-01-13 09:27:19 +03:00
|
|
|
s.set_marker()
|
2020-01-12 18:31:28 +03:00
|
|
|
self.ae(s.marked_cells(), [])
|
|
|
|
|
|
|
|
def mark_x(text):
|
|
|
|
col = 0
|
|
|
|
for i, c in enumerate(text):
|
|
|
|
if c == 'x':
|
|
|
|
col += 1
|
|
|
|
yield i, i, col
|
|
|
|
|
2020-01-13 09:27:19 +03:00
|
|
|
s.set_marker(marker_from_function(mark_x))
|
2020-01-12 18:31:28 +03:00
|
|
|
self.ae(s.marked_cells(), [(0, 1, 1), (2, 1, 2), (4, 1, 3)])
|
2020-01-15 04:41:34 +03:00
|
|
|
s = self.create_screen(lines=5, scrollback=10)
|
|
|
|
for i in range(15):
|
|
|
|
s.draw(str(i))
|
|
|
|
if i != 14:
|
|
|
|
s.carriage_return(), s.linefeed()
|
|
|
|
s.set_marker(marker_from_regex(r'\d+', 3))
|
|
|
|
for i in range(10):
|
|
|
|
self.assertTrue(s.scroll_to_next_mark())
|
|
|
|
self.ae(s.scrolled_by, i + 1)
|
|
|
|
self.ae(s.scrolled_by, 10)
|
|
|
|
for i in range(10):
|
|
|
|
self.assertTrue(s.scroll_to_next_mark(0, False))
|
|
|
|
self.ae(s.scrolled_by, 10 - i - 1)
|
|
|
|
self.ae(s.scrolled_by, 0)
|
2020-04-12 10:58:21 +03:00
|
|
|
|
|
|
|
s = self.create_screen()
|
|
|
|
s.draw('🐈ab')
|
|
|
|
s.set_marker(marker_from_regex('🐈', 3))
|
|
|
|
self.ae(s.marked_cells(), cells(0, 1))
|
|
|
|
s.set_marker(marker_from_regex('🐈a', 3))
|
|
|
|
self.ae(s.marked_cells(), cells(0, 1, 2))
|
2020-04-12 14:24:38 +03:00
|
|
|
s.set_marker(marker_from_regex('a', 3))
|
|
|
|
self.ae(s.marked_cells(), cells(2))
|
2020-04-12 10:58:21 +03:00
|
|
|
s = self.create_screen(cols=20)
|
|
|
|
s.tab()
|
|
|
|
s.draw('ab')
|
|
|
|
s.set_marker(marker_from_regex('a', 3))
|
|
|
|
self.ae(s.marked_cells(), cells(8))
|
|
|
|
s.set_marker(marker_from_regex('\t', 3))
|
2020-04-12 14:31:39 +03:00
|
|
|
self.ae(s.marked_cells(), cells(*range(8)))
|