From a7e0ee239b33ec653342412c475f5c6d40387717 Mon Sep 17 00:00:00 2001 From: fan wu <336798967+FanWu-ai@users.noreply.github.com> Date: Mon, 19 Oct 2026 06:15:08 +0900 Subject: [PATCH] Identify bracket cursor highlighting in source coordinates --- src/prompt_toolkit/layout/processors.py | 6 ++- tests/test_bracket_processor.py | 62 +++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tests/test_bracket_processor.py diff --git a/src/prompt_toolkit/layout/processors.py b/src/prompt_toolkit/layout/processors.py index 139f07c3e..f9784bfa5 100644 --- a/src/prompt_toolkit/layout/processors.py +++ b/src/prompt_toolkit/layout/processors.py @@ -420,11 +420,15 @@ def apply_transformation( if positions: for row, col in positions: if row == lineno: + on_cursor = ( + row == document.cursor_position_row + and col == document.cursor_position_col + ) col = source_to_display(col) fragments = explode_text_fragments(fragments) style, text, *_ = fragments[col] - if col == document.cursor_position_col: + if on_cursor: style += " class:matching-bracket.cursor " else: style += " class:matching-bracket.other " diff --git a/tests/test_bracket_processor.py b/tests/test_bracket_processor.py new file mode 100644 index 000000000..1505cc36a --- /dev/null +++ b/tests/test_bracket_processor.py @@ -0,0 +1,62 @@ +from __future__ import annotations + +import pytest + +from prompt_toolkit.document import Document +from prompt_toolkit.layout.controls import BufferControl +from prompt_toolkit.layout.processors import ( + HighlightMatchingBracketProcessor, + TransformationInput, +) + + +@pytest.mark.parametrize("cursor_position", [0, 2]) +@pytest.mark.parametrize("prefix", ["", ">> "]) +def test_matching_bracket_cursor_style_uses_source_row_and_column( + cursor_position, prefix +): + document = Document("(\n)", cursor_position=cursor_position) + processor = HighlightMatchingBracketProcessor() + for lineno, line in enumerate(document.lines): + result = processor.apply_transformation( + TransformationInput( + buffer_control=BufferControl(), + document=document, + lineno=lineno, + source_to_display=lambda i: i + len(prefix), + fragments=[("", prefix + line)], + width=80, + height=24, + ) + ) + style = result.fragments[len(prefix)][0] + if lineno == document.cursor_position_row: + assert "class:matching-bracket.cursor" in style + assert "class:matching-bracket.other" not in style + else: + assert "class:matching-bracket.other" in style + assert "class:matching-bracket.cursor" not in style + + +@pytest.mark.parametrize("text", ["()", "(\n)"]) +@pytest.mark.parametrize("prefix", ["", ">> "]) +def test_matching_brackets_after_closing_bracket_keep_other_style(text, prefix): + document = Document(text, cursor_position=len(text)) + processor = HighlightMatchingBracketProcessor() + styles = [] + for lineno, line in enumerate(document.lines): + result = processor.apply_transformation( + TransformationInput( + buffer_control=BufferControl(), + document=document, + lineno=lineno, + source_to_display=lambda i: i + len(prefix), + fragments=[("", prefix + line)], + width=80, + height=24, + ) + ) + styles.extend(style for style, char in result.fragments if char in "()") + assert len(styles) == 2 + assert all("class:matching-bracket.other" in style for style in styles) + assert all("class:matching-bracket.cursor" not in style for style in styles)