Repository: spyder-ide/spyder

Issue:
Find occurrences backwards with Shift + Enter (inside find or find/replace mode)
Right now it finds the occurrences forward with Enter. 


Discussion:

Resolving patch:
diff --git a/spyder/widgets/findreplace.py b/spyder/widgets/findreplace.py
--- a/spyder/widgets/findreplace.py
+++ b/spyder/widgets/findreplace.py
@@ -15,7 +15,7 @@
 import re
 
 # Third party imports
-from qtpy.QtCore import Qt, QTimer, Signal, Slot
+from qtpy.QtCore import Qt, QTimer, Signal, Slot, QEvent
 from qtpy.QtGui import QTextCursor
 from qtpy.QtWidgets import (QCheckBox, QGridLayout, QHBoxLayout, QLabel,
                             QSizePolicy, QWidget)
@@ -44,6 +44,8 @@ class FindReplace(QWidget):
              True: "",
              None: ""}
     visibility_changed = Signal(bool)
+    return_shift_pressed = Signal()
+    return_pressed = Signal()
 
     def __init__(self, parent, enable_replace=False):
         QWidget.__init__(self, parent)
@@ -62,9 +64,15 @@ def __init__(self, parent, enable_replace=False):
         # Find layout
         self.search_text = PatternComboBox(self, tip=_("Search string"),
                                            adjust_to_minimum=False)
-        self.search_text.valid.connect(
-                     lambda state:
+
+        self.return_shift_pressed.connect(
+                lambda:
+                self.find(changed=False, forward=False, rehighlight=False))
+
+        self.return_pressed.connect(
+                     lambda:
                      self.find(changed=False, forward=True, rehighlight=False))
+
         self.search_text.lineEdit().textEdited.connect(
                                                      self.text_has_been_edited)
         
@@ -145,7 +153,28 @@ def __init__(self, parent, enable_replace=False):
         self.highlight_timer.setSingleShot(True)
         self.highlight_timer.setInterval(1000)
         self.highlight_timer.timeout.connect(self.highlight_matches)
-        
+        self.search_text.installEventFilter(self)
+
+
+    def eventFilter(self, widget, event):
+        """Event filter for search_text widget.
+
+        Emits signals when presing Enter and Shift+Enter.
+        This signals are used for search forward and backward.
+        """
+        if (event.type() == QEvent.KeyPress):
+            key = event.key()
+            shift = event.modifiers() & Qt.ShiftModifier
+
+            if key == Qt.Key_Return:
+                if shift:
+                    self.return_shift_pressed.emit()
+                else:
+                    self.return_pressed.emit()
+
+        return super(FindReplace, self).eventFilter(widget, event)
+
+
     def create_shortcuts(self, parent):
         """Create shortcuts for this widget"""
         # Configurable


Test patch:
diff --git a/spyder/widgets/tests/test_editor.py b/spyder/widgets/tests/test_editor.py
--- a/spyder/widgets/tests/test_editor.py
+++ b/spyder/widgets/tests/test_editor.py
@@ -155,6 +155,36 @@ def test_replace_current_selected_line(editor_find_replace_bot):
     qtbot.keyPress(finder.replace_text, Qt.Key_Return)
     assert editor.toPlainText()[0:-1] == expected_new_text
 
+def test_replace_enter_press(editor_find_replace_bot):
+    """Test advance forward pressing Enter, and backwards with Shift+Enter."""
+    editor_stack, editor, finder, qtbot = editor_find_replace_bot
+    text = '  \nspam \nspam \nspam '
+    editor.set_text(text)
+    finder.show()
+
+    finder.search_text.add_text('spam')
+
+    # search forward
+    qtbot.keyPress(finder.search_text, Qt.Key_Return)
+    assert editor.get_cursor_line_column() == (1,4)
+
+    qtbot.keyPress(finder.search_text, Qt.Key_Return)
+    assert editor.get_cursor_line_column() == (2,4)
+
+    qtbot.keyPress(finder.search_text, Qt.Key_Return)
+    assert editor.get_cursor_line_column() == (3,4)
+
+    # search backwards
+    qtbot.keyPress(finder.search_text, Qt.Key_Return, modifier=Qt.ShiftModifier)
+    assert editor.get_cursor_line_column() == (2,4)
+
+    qtbot.keyPress(finder.search_text, Qt.Key_Return, modifier=Qt.ShiftModifier)
+    assert editor.get_cursor_line_column() == (1,4)
+
+    qtbot.keyPress(finder.search_text, Qt.Key_Return, modifier=Qt.ShiftModifier)
+    assert editor.get_cursor_line_column() == (3,4)
+
+
 def test_advance_cell(editor_cells_bot):
     editor_stack, editor, qtbot = editor_cells_bot