From cf6f2d885515056adc260a4613f89dc206b69aaf Mon Sep 17 00:00:00 2001 From: Haozhe Zhang Date: Sun, 12 Jul 2026 22:19:51 -0700 Subject: [PATCH] Stop Return in the search box from deleting the matched text QLineEdit ignores Return once it has emitted returnPressed. The search widget is a child of the editor, so the key propagated up and was inserted into the document. highlight_current_match() selects the current match with setTextCursor(), so the inserted newline replaced the match: searching for 'key' in 'key=1' and pressing Return left '\n=1'. --- cq_editor/widgets/code_editor.py | 15 +++++++++++++++ tests/test_app.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/cq_editor/widgets/code_editor.py b/cq_editor/widgets/code_editor.py index 52ffc7bc..df09e12c 100644 --- a/cq_editor/widgets/code_editor.py +++ b/cq_editor/widgets/code_editor.py @@ -57,6 +57,21 @@ def setup_ui(self): layout.addWidget(self.close_button) self.setLayout(layout) + def keyPressEvent(self, event): + """ + Keeps Return from reaching the editor. + + QLineEdit ignores Return after emitting returnPressed, and this widget + is a child of the editor, so the key would otherwise propagate up and + be inserted into the document. The current match is selected there, + which means the newline replaces the matched text. + """ + if event.key() in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter): + event.accept() + return + + super(SearchWidget, self).keyPressEvent(event) + def on_search_text_changed(self, text): """ Called as the user types text into the search field. diff --git a/tests/test_app.py b/tests/test_app.py index 76deda64..79c9d20c 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -970,6 +970,35 @@ def test_search(editor): qtbot.keyClick(editor, Qt.Key_F3, modifier=Qt.AltModifier) +def test_search_return_does_not_edit_document(editor): + """ + Pressing Return in the search box should only advance to the next match, + never change the code. + """ + qtbot, editor = editor + + editor.set_text(base_editor_text) + + # Open the search box and search for a term with more than one match + qtbot.keyClick(editor, Qt.Key_F, modifier=Qt.ControlModifier) + qtbot.keyClicks(editor.search_widget.search_input, "cq") + assert editor.search_widget.match_label.text() == "1 of 2" + + # The current match is selected in the editor, so a Return that reaches it + # would replace the matched text with a newline + qtbot.keyClick(editor.search_widget.search_input, Qt.Key_Return) + assert editor.search_widget.match_label.text() == "2 of 2" + assert editor.get_text_with_eol() == base_editor_text + + qtbot.keyClick(editor.search_widget.search_input, Qt.Key_Return) + assert editor.search_widget.match_label.text() == "1 of 2" + assert editor.get_text_with_eol() == base_editor_text + + # Escape still closes the search box from within the search input + qtbot.keyClick(editor.search_widget.search_input, Qt.Key_Escape) + assert not editor.search_widget.isVisible() + + def test_line_number_area(editor): """ Tests to make sure the line number area on the left of the editor is working correctly.