Repository: spyder-ide/spyder

Issue:
Deleting space before a word trigger meaningless completion
Hi spyder devs,
I've find a new way of improving the completion:

## Problem Description
Deleting space before a word trigger meaningless completion.

### What steps reproduce the problem?

1. In a new document type `None`;
2. add a space before it;
3. remove this space.

### What is the expected output? What do you see instead?
I would expect nothing, I see the completion with all possibilities.


## Versions
<!--- You can get this information from Help > About Spyder...
or (if Spyder won't launch) the "conda list" command
from the Anaconda Prompt/Terminal/command line. --->

* Spyder version: 4.1.3
* Python version: 3.8

I'm sorry, but this time I don't have time to investigate more.


Discussion:
The same problem, when real-time code completion is available
Hi @ElieGouzien and @leavor,

We are going to fix this for spyder 4.1.4 release. Thanks for reporting! 

Resolving patch:
diff --git a/spyder/plugins/editor/widgets/codeeditor.py b/spyder/plugins/editor/widgets/codeeditor.py
--- a/spyder/plugins/editor/widgets/codeeditor.py
+++ b/spyder/plugins/editor/widgets/codeeditor.py
@@ -4072,6 +4072,16 @@ def _handle_completions(self):
                 self._last_pressed_key = None
                 return
 
+        # Correctly handle completions when Backspace key is pressed.
+        # We should not show the widget if deleting a space before a word.
+        if key == Qt.Key_Backspace:
+            cursor.setPosition(pos - 1, QTextCursor.MoveAnchor)
+            cursor.select(QTextCursor.WordUnderCursor)
+            prev_text = to_text_string(cursor.selectedText())
+            cursor.setPosition(pos + 1, QTextCursor.MoveAnchor)
+            if prev_text == '':
+                return
+
         # Text might be after a dot '.'
         if text == '':
             cursor.setPosition(pos - 1, QTextCursor.MoveAnchor)
@@ -4089,8 +4099,11 @@ def _handle_completions(self):
 
         self.document_did_change(text)
 
+        is_backspace = (
+            self.is_completion_widget_visible() and key == Qt.Key_Backspace)
+
         if (len(text) >= self.automatic_completions_after_chars
-                and self._last_key_pressed_text) or key == Qt.Key_Backspace:
+                and self._last_key_pressed_text or is_backspace):
             # Perform completion on the fly
             if self.automatic_completions and not self.in_comment_or_string():
                 # Variables can include numbers and underscores


Test patch:
diff --git a/spyder/plugins/editor/widgets/tests/test_completions_hide.py b/spyder/plugins/editor/widgets/tests/test_completions_hide.py
--- a/spyder/plugins/editor/widgets/tests/test_completions_hide.py
+++ b/spyder/plugins/editor/widgets/tests/test_completions_hide.py
@@ -19,7 +19,8 @@
 def test_automatic_completions_hide_complete(lsp_codeeditor, qtbot):
     """Test on-the-fly completion closing when already complete.
 
-    Regression test for issue #11600 and pull requests #11824 and #12140.
+    Regression test for issue #11600 and pull requests #11824, #12140
+    and #12710.
     """
     code_editor, _ = lsp_codeeditor
     completion = code_editor.completion_widget
@@ -54,8 +55,49 @@ def test_automatic_completions_hide_complete(lsp_codeeditor, qtbot):
     qtbot.wait(500)
     assert completion.isHidden()
 
+    # Hide if removing spaces before a word
+    code_editor.moveCursor(cursor.End)
+    qtbot.keyPress(code_editor, Qt.Key_Enter, delay=300)  # newline
+    qtbot.keyClicks(code_editor, '   None')
+    qtbot.wait(500)
+    code_editor.moveCursor(cursor.End - 4)
+    qtbot.keyPress(code_editor, Qt.Key_Backspace, delay=300)
+    assert completion.isHidden()
+
     code_editor.toggle_code_snippets(True)
 
 
+@pytest.mark.slow
+@pytest.mark.first
+@flaky(max_runs=5)
+def test_automatic_completions_widget_visible(lsp_codeeditor, qtbot):
+    """
+    Test on-the-fly completions when the widget is visible and the Backspace
+    key is pressed.
+
+    Regression test for PR #12710
+    """
+    code_editor, _ = lsp_codeeditor
+    completion = code_editor.completion_widget
+    code_editor.toggle_code_snippets(False)
+
+    code_editor.set_text('import math')
+    cursor = code_editor.textCursor()
+    code_editor.moveCursor(cursor.End)
+    qtbot.keyPress(code_editor, Qt.Key_Enter, delay=300)  # newline
+
+    with qtbot.waitSignal(completion.sig_show_completions,
+                          timeout=10000) as sig:
+        qtbot.keyClicks(code_editor, 'math.aco')
+
+    assert completion.isVisible()
+
+    qtbot.keyPress(code_editor, Qt.Key_Backspace, delay=300)
+    assert completion.isVisible()
+
+    qtbot.keyPress(code_editor, Qt.Key_Backspace, delay=300)
+    assert completion.isVisible()
+
+
 if __name__ == '__main__':
     pytest.main(['test_completion.py', '--run-slow'])