Allow backspace to wrap cursor to previous line

Fixes #8841
This commit is contained in:
Kovid Goyal
2025-07-23 08:56:54 +05:30
parent 55a2f2c55c
commit 45b2678db1
14 changed files with 87 additions and 29 deletions

View File

@@ -766,7 +766,7 @@ class TestGraphics(BaseTest):
s.draw("\U0010EEEE\u0305\u0305\U0010EEEE\u0305\u030D")
# These two characters will be two separate refs (not contiguous).
s.draw("\U0010EEEE\u0305\u0305\U0010EEEE\u0305\u030E")
s.cursor_back(4)
s.cursor_move(4)
s.update_only_line_graphics_data()
refs = layers(s)
self.ae(len(refs), 3)
@@ -786,7 +786,7 @@ class TestGraphics(BaseTest):
# The second image, 2x1
s.apply_sgr("38;2;42;43;44")
s.draw("\U0010EEEE\u0305\u030D\U0010EEEE\u0305\u030E")
s.cursor_back(2)
s.cursor_move(2)
s.update_only_line_graphics_data()
refs = layers(s)
self.ae(len(refs), 2)
@@ -804,7 +804,7 @@ class TestGraphics(BaseTest):
s.draw("\U0010EEEE\u0305\u0305\U0010EEEE\u0305\U0010EEEE\U0010EEEE\u0305")
# full row 1 of the first image
s.draw("\U0010EEEE\u030D\U0010EEEE\U0010EEEE\U0010EEEE\u030D\u0310")
s.cursor_back(8)
s.cursor_move(8)
s.update_only_line_graphics_data()
refs = layers(s)
self.ae(len(refs), 2)
@@ -826,7 +826,7 @@ class TestGraphics(BaseTest):
# This one will have id=43, which does not exist.
s.apply_sgr("38;2;0;0;43")
s.draw("\U0010EEEE\u0305\U0010EEEE\U0010EEEE\U0010EEEE")
s.cursor_back(4)
s.cursor_move(4)
s.update_only_line_graphics_data()
refs = layers(s)
self.ae(len(refs), 0)
@@ -842,7 +842,7 @@ class TestGraphics(BaseTest):
s.draw("\U0010EEEE\u0305\u0305\u059C\U0010EEEE\u0305\u030D\u059C")
# Check that we can continue by using implicit row/column specification.
s.draw("\U0010EEEE\u0305\U0010EEEE")
s.cursor_back(6)
s.cursor_move(6)
s.update_only_line_graphics_data()
refs = layers(s)
self.ae(len(refs), 2)
@@ -856,7 +856,7 @@ class TestGraphics(BaseTest):
s.draw("\U0010EEEE\u0305\u0305\u0305\U0010EEEE")
s.apply_sgr("38;5;43")
s.draw("\U0010EEEE\u0305\u0305\u059C\U0010EEEE\U0010EEEE\u0305\U0010EEEE")
s.cursor_back(6)
s.cursor_move(6)
s.update_only_line_graphics_data()
refs = layers(s)
self.ae(len(refs), 2)

View File

@@ -353,7 +353,7 @@ class TestParser(BaseTest):
s = self.create_screen()
pb = partial(self.parse_bytes_dump, s)
pb('abcde', 'abcde')
s.cursor_back(5)
s.cursor_move(5)
pb('x\033[2@y', 'x', ('screen_insert_characters', 2), 'y')
self.ae(str(s.line(0)), 'xy bc')
pb('x\033[2;7@y', 'x', ('CSI code @ has 2 > 1 parameters',), 'y')

View File

@@ -44,7 +44,7 @@ class TestScreen(BaseTest):
s.reset(), s.reset_dirty()
s.set_mode(IRM)
s.draw('12345' * 5)
s.cursor_back(5)
s.cursor_move(5)
self.ae(s.cursor.x, 0), self.ae(s.cursor.y, 4)
s.reset_dirty()
s.draw('ab')
@@ -98,7 +98,7 @@ class TestScreen(BaseTest):
s.set_mode(IRM)
s.draw(text * 5)
self.ae(str(s.line(0)), text)
s.cursor_back(5)
s.cursor_move(5)
self.ae(s.cursor.x, 0), self.ae(s.cursor.y, 4)
s.reset_dirty()
s.draw('a\u0306b')
@@ -162,7 +162,7 @@ class TestScreen(BaseTest):
s.reset(), s.reset_dirty()
s.draw('abcde')
s.cursor.bold = True
s.cursor_back(4)
s.cursor_move(4)
s.reset_dirty()
self.ae(s.cursor.x, 1)
@@ -170,11 +170,11 @@ class TestScreen(BaseTest):
s.insert_characters(2)
self.ae(str(s.line(0)), 'a bc')
self.assertTrue(s.line(0).cursor_from(1).bold)
s.cursor_back(1)
s.cursor_move(1)
s.insert_characters(20)
self.ae(str(s.line(0)), '')
s.draw('xココ')
s.cursor_back(5)
s.cursor_move(5)
s.reset_dirty()
s.insert_characters(1)
self.ae(str(s.line(0)), ' xコ')
@@ -270,7 +270,7 @@ class TestScreen(BaseTest):
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()
s.cursor_move()
self.ae((s.cursor.x, s.cursor.y), (2, 1))
s.cursor_down()
self.ae((s.cursor.x, s.cursor.y), (2, 2))
@@ -534,6 +534,28 @@ class TestScreen(BaseTest):
s.draw('aaaX\tbbbb')
self.ae(str(s.line(0)) + str(s.line(1)), 'aaaXbbbb')
def test_backspace(self):
s = self.create_screen()
q = 'a'*s.columns
def backspace(use_bs=True):
if use_bs: # this is how the kernel implements backspace
s.draw('\x08 \x08')
else:
s.cursor_move(1)
s.draw(' ')
s.cursor_move(1)
for use_bs in (True, False):
s.reset()
s.draw(q)
s.draw('b')
backspace(use_bs)
self.ae(str(s.line(0)), q)
self.ae(str(s.line(1)), ' ')
self.ae(s.cursor.x, 0)
backspace(use_bs)
self.ae(str(s.line(0)), q[:-1] + ' ')
self.ae(str(s.line(1)), ' ')
def test_margins(self):
# Taken from vttest/main.c
s = self.create_screen(cols=80, lines=24)