diff --git a/babi/file.py b/babi/file.py index e9eb893..100c029 100644 --- a/babi/file.py +++ b/babi/file.py @@ -623,6 +623,7 @@ class File: self.buf.up(margin) self.buf.x = len(self.buf[self.buf.y]) self.buf[self.buf.y] += self.buf.pop(self.buf.y + 1) + self.buf.restore_eof_invariant() def _sort(self, margin: Margin, s_y: int, e_y: int) -> None: # self.buf intentionally does not support slicing so we use islice diff --git a/babi/hl/trailing_whitespace.py b/babi/hl/trailing_whitespace.py index 47c0ccf..383241a 100644 --- a/babi/hl/trailing_whitespace.py +++ b/babi/hl/trailing_whitespace.py @@ -35,8 +35,8 @@ class TrailingWhitespace: self.regions[idx] = self._trailing_ws(lines[idx]) def _del_cb(self, lines: Buf, idx: int, victim: str) -> None: - assert idx < len(self.regions) # currently all `del` happen on screen - del self.regions[idx] + if idx < len(self.regions): + del self.regions[idx] def _ins_cb(self, lines: Buf, idx: int) -> None: if idx < len(self.regions): diff --git a/tests/features/cut_uncut_test.py b/tests/features/cut_uncut_test.py index 237d889..886107d 100644 --- a/tests/features/cut_uncut_test.py +++ b/tests/features/cut_uncut_test.py @@ -132,3 +132,21 @@ def test_selection_cut_uncut_selection_offscreen_x(run): h.await_text_missing('hello') h.press('^K') h.await_text('hello\n') + + +def test_selection_cut_uncut_at_end_of_file(run, ten_lines): + with run(str(ten_lines)) as h, and_exit(h): + h.press('S-Down') + h.press('S-Right') + h.press('^K') + h.await_text_missing('line_0') + h.await_text_missing('line_1') + h.await_text('ine_1') + + h.press('^End') + h.press('^U') + h.await_text('line_0\nl\n') + h.await_cursor_position(x=1, y=11) + + h.press('Down') + h.await_cursor_position(x=0, y=12)