From e6fe1e1b3ddc3cbcb84ce1e7c6682f4907e52be8 Mon Sep 17 00:00:00 2001 From: kzahiri1 Date: Mon, 5 Oct 2026 16:59:23 -0700 Subject: [PATCH] Clamp negative rows in translate_row_col_to_index The method documents that a negative row becomes zero. The row was used as a list index, so -1 selected the last line. Co-authored-by: Cursor --- src/prompt_toolkit/document.py | 12 ++++++------ tests/test_document.py | 9 +++++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/prompt_toolkit/document.py b/src/prompt_toolkit/document.py index 003a7852e..419feca06 100644 --- a/src/prompt_toolkit/document.py +++ b/src/prompt_toolkit/document.py @@ -325,16 +325,16 @@ def translate_row_col_to_index(self, row: int, col: int) -> int: Negative row/col values are turned into zero. """ + # Clamp before indexing. A negative row is a valid list index and + # would otherwise select a line from the end of the document. + if row < 0: + row = 0 try: result = self._line_start_indexes[row] line = self.lines[row] except IndexError: - if row < 0: - result = self._line_start_indexes[0] - line = self.lines[0] - else: - result = self._line_start_indexes[-1] - line = self.lines[-1] + result = self._line_start_indexes[-1] + line = self.lines[-1] result += max(0, min(col, len(line))) diff --git a/tests/test_document.py b/tests/test_document.py index ff54310d5..e5b172b5a 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -66,6 +66,15 @@ def test_translate_index_to_position(document): assert pos == (0, 0) +def test_translate_row_col_to_index_clamps_negative_row(): + # Negative rows are documented to become zero. List indexing would + # otherwise select lines from the end of the document. + document = Document("one\ntwo\nthree") + for row in (-1, -2, -3, -4): + assert document.translate_row_col_to_index(row, 0) == 0 + assert document.translate_row_col_to_index(-1, 1) == 1 + + def test_is_cursor_at_the_end(document): assert Document("hello", 5).is_cursor_at_the_end assert not Document("hello", 4).is_cursor_at_the_end