diff --git a/kitty/screen.py b/kitty/screen.py index 0ea4a04f5..f3049d46b 100644 --- a/kitty/screen.py +++ b/kitty/screen.py @@ -70,7 +70,7 @@ class Screen(QObject): @property def display(self) -> Sequence[str]: - return [str(l) for l in self.linebuf] + return tuple(map(str, self.linebuf)) def reset(self): """Resets the terminal to its initial state. @@ -630,7 +630,7 @@ class Screen(QObject): line.clear_text(s, n) else: line.apply_cursor(c, s, n, clear_char=True) - self.update_cell_range(y, s, min(s + n, self.columns - 1)) + self.update_cell_range(y, s, min(s + n, self.columns) - 1) def erase_in_display(self, how=0, private=False): """Erases display in a specific way. @@ -643,28 +643,33 @@ class Screen(QObject): including cursor position. * ``2`` -- Erases complete display. All lines are erased and changed to single-width. Cursor does not move. - :param bool private: when ``True`` character attributes are left - unchanged **not implemented**. + :param bool private: when ``True`` character attributes are left unchanged """ if how == 0: # a) erase from cursor to the end of the display, including # the cursor, - interval = range(self.cursor.y + 1, self.lines) + interval = self.cursor.y + 1, self.lines elif how == 1: # b) erase from the beginning of the display to the cursor, # including it, - interval = range(self.cursor.y) + interval = 0, self.cursor.y elif how == 2: # c) erase the whole display. - interval = range(self.lines) + interval = 0, self.lines + else: + return - for line in interval: - self.buffer[line][:] = \ - (self.cursor.attrs for _ in range(self.columns)) + if interval[1] > interval[0]: + for line in range(*interval): + if private: + self.linebuf[line].clear_text(0, self.columns) + else: + self.linebuf[line].apply_cursor(self.cursor, 0, self.columns, clear_char=True) + self.update_line_range(interval[0], interval[1] - 1) - # In case of 0 or 1 we have to erase the line with the cursor. - if how == 0 or how == 1: - self.erase_in_line(how) + # In case of 0 or 1 we have to erase the line with the cursor also + if how != 2: + self.erase_in_line(how, private=private) def set_tab_stop(self): """Sets a horizontal tab stop at cursor position.""" diff --git a/kitty/tracker.py b/kitty/tracker.py index 3160b748a..288e6df03 100644 --- a/kitty/tracker.py +++ b/kitty/tracker.py @@ -81,7 +81,7 @@ class ChangeTracker(QObject): else: if self.changed_lines: for y in self.changed_lines: - del self.changed_cells[y] + self.changed_cells.pop(y, None) for y, cell_ranges in self.changed_cells.items(): self.changed_cells[y] = tuple(merge_ranges(cell_ranges)) changes = {'screen': self.screen_changed, 'cursor': self.changed_cursor, 'lines': self.changed_lines, diff --git a/kitty_tests/screen.py b/kitty_tests/screen.py index 79722f0db..04001ec8c 100644 --- a/kitty_tests/screen.py +++ b/kitty_tests/screen.py @@ -153,7 +153,7 @@ class TestScreen(BaseTest): init() s.erase_in_line(1) self.ae(str(s.linebuf[0]), ' cde') - self.assertChanges(t, cells={0: ((0, 2),)}) + self.assertChanges(t, cells={0: ((0, 1),)}) init() s.erase_in_line(2) self.ae(str(s.linebuf[0]), ' ') @@ -161,3 +161,34 @@ class TestScreen(BaseTest): init() s.erase_in_line(2, private=True) self.ae((False, False, False, False, False), tuple(map(lambda i: s.linebuf[0].cursor_from(i).bold, range(5)))) + + def test_erase_in_screen(self): + s, t = self.create_screen() + + def init(): + s.reset() + s.draw(b'12345' * 5) + t.reset() + s.cursor.x, s.cursor.y = 2, 1 + s.cursor.bold = True + + init() + s.erase_in_display() + self.ae(s.display, ('12345', '12 ', ' ', ' ', ' ')) + self.assertChanges(t, lines={2, 3, 4}, cells={1: ((2, 4),)}) + + init() + s.erase_in_display(1) + self.ae(s.display, (' ', ' 45', '12345', '12345', '12345')) + self.assertChanges(t, lines={0}, cells={1: ((0, 2),)}) + + init() + s.erase_in_display(2) + self.ae(s.display, (' ', ' ', ' ', ' ', ' ')) + self.assertChanges(t, lines=set(range(5))) + self.assertTrue(s.linebuf[0].cursor_from(1).bold) + init() + s.erase_in_display(2, private=True) + self.ae(s.display, (' ', ' ', ' ', ' ', ' ')) + self.assertChanges(t, lines=set(range(5))) + self.assertFalse(s.linebuf[0].cursor_from(1).bold)