Repository: spyder-ide/spyder

Issue:
Autocomplete replace "import" keyword
<!--- **PLEASE READ:** When submitting here, please ensure you've completed the following checklist and checked the boxes to confirm. Issue reports without it may be closed. Thanks! --->

## Problem Description
autocomplete replace import keyword.

![autocomplete](https://user-images.githubusercontent.com/22970578/51615069-4cfaa580-1f6a-11e9-895b-5429b0674faa.gif)



### What steps reproduce the problem?

1. type "from \<module\> import"
2. type "\<space\>"
3. type "\<tab\>"
4. select 

### What is the expected output? What do you see instead?



### Paste Traceback/Error Below (if applicable)
<!--- Copy from error dialog or View > Panes > Internal Console --->

```python-traceback

PASTE TRACEBACK HERE

```

## 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: spyder 4.0 dev lastest master [4166830](https://github.com/spyder-ide/spyder/commit/416683058aa126499b5777f00f12f644b5f67a48)
* Python version: 3.6.7
* Qt version: 5.9.6
* PyQt version: 5.9.2
* Operating System name/version: 4.20.1-1-MANJARO

IPython >=4.0     :  6.4.0 (OK)
cython >=0.21     :  0.28.2 (OK)
jedi >=0.9.0      :  0.12.0 (OK)
matplotlib >=2.0.0:  3.0.2 (OK)
nbconvert >=4.0   :  5.3.1 (OK)
numpy >=1.7       :  1.16.0 (OK)
pandas >=0.13.1   :  0.23.0 (OK)
pycodestyle >=2.3 :  2.4.0 (OK)
pyflakes >=0.6.0  :  1.6.0 (OK)
pygments >=2.0    :  2.2.0 (OK)
pylint >=0.25     :  1.8.4 (OK)
qtconsole >=4.2.0 :  4.3.1 (OK)
rope >=0.9.4      :  0.10.7 (OK)
sphinx >=0.6.6    :  1.7.4 (OK)
sympy >=0.7.3     :  1.1.1 (OK)


Discussion:
@dalthviz, please take a look at this one. It seems to be a side effect of your previous work on code completion.
@Khalilsqu, PR #8600 should fix that problem on Windows (but that's different from the one reported here by @ok97465).

Resolving patch:
diff --git a/spyder/widgets/mixins.py b/spyder/widgets/mixins.py
--- a/spyder/widgets/mixins.py
+++ b/spyder/widgets/mixins.py
@@ -358,11 +358,11 @@ def get_current_word(self, completion=False):
             # (see below), the word to the left of the cursor won't be
             # selected), but only if the first character to the left is not a
             # white space too.
+            def is_space(move):
+                curs = self.textCursor()
+                curs.movePosition(move, QTextCursor.KeepAnchor)
+                return not to_text_string(curs.selectedText()).strip()
             if not completion:
-                def is_space(move):
-                    curs = self.textCursor()
-                    curs.movePosition(move, QTextCursor.KeepAnchor)
-                    return not to_text_string(curs.selectedText()).strip()
                 if is_space(QTextCursor.NextCharacter):
                     if is_space(QTextCursor.PreviousCharacter):
                         return
@@ -374,7 +374,9 @@ def is_special_character(move):
                     text_cursor = to_text_string(curs.selectedText()).strip()
                     return len(re.findall(r'([^\d\W]\w*)',
                                           text_cursor, re.UNICODE)) == 0
-                if is_special_character(QTextCursor.NextCharacter):
+                if is_space(QTextCursor.PreviousCharacter):
+                    return
+                if (is_special_character(QTextCursor.NextCharacter)):
                     cursor.movePosition(QTextCursor.WordLeft)
 
         cursor.select(QTextCursor.WordUnderCursor)


Test patch:
diff --git a/spyder/plugins/editor/tests/test_introspection.py b/spyder/plugins/editor/tests/test_introspection.py
--- a/spyder/plugins/editor/tests/test_introspection.py
+++ b/spyder/plugins/editor/tests/test_introspection.py
@@ -72,6 +72,32 @@ def get_spyder_pythonpath(*args):
     os.environ['SPY_TEST_USE_INTROSPECTION'] = 'False'
     editor.main.lspmanager.shutdown()
 
+
+@pytest.mark.slow
+def test_space_completion(setup_editor):
+    """Validate completion's space character handling."""
+    editor, qtbot = setup_editor
+    code_editor = editor.get_focus_widget()
+    completion = code_editor.completion_widget
+
+    # Set cursor to start
+    code_editor.go_to_line(1)
+
+    # Complete from numpy --> from numpy import
+    qtbot.keyClicks(code_editor, 'from numpy ')
+    qtbot.wait(20000)
+
+    # press tab and get completions
+    with qtbot.waitSignal(completion.sig_show_completions,
+                          timeout=10000) as sig:
+        qtbot.keyPress(code_editor, Qt.Key_Tab)
+    assert "import" in [x['label'] for x in sig.args[0]]
+
+    # enter should accept first completion
+    qtbot.keyPress(completion, Qt.Key_Enter, delay=1000)
+    assert code_editor.toPlainText() == 'from numpy import\n'
+
+
 @pytest.mark.slow
 @pytest.mark.skipif(PY2, reason="Segfaults with other tests on Py2.")
 @pytest.mark.skipif(os.name == 'nt' and not PY2,