Keyword completions are no longer possible directly after a number, fixes #1085

This commit is contained in:
Dave Halter
2019-06-26 15:04:46 +02:00
parent 265abe1d08
commit fafd6b2ac6
5 changed files with 32 additions and 8 deletions

View File

@@ -171,7 +171,10 @@ class Completion:
elif type_ == 'for_stmt':
allowed_transitions.append('else')
completion_names = list(self._get_keyword_completion_names(allowed_transitions))
completion_names = []
current_line = self._code_lines[self._position[0] - 1][:self._position[1]]
if not current_line or current_line[-1] in ' \t.;':
completion_names += self._get_keyword_completion_names(allowed_transitions)
if any(t in allowed_transitions for t in (PythonTokenTypes.NAME,
PythonTokenTypes.INDENT)):

View File

@@ -18,10 +18,12 @@ int(str)
str..
#? []
a(0):.
#? 2 ['and', 'or', 'if', 'is', 'in', 'not']
#? 2 []
0x0
#? ['and', 'or', 'if', 'is', 'in', 'not']
#? []
1j
#? ['and', 'or', 'if', 'is', 'in', 'not']
1j
x = None()
#?
x

View File

@@ -279,7 +279,7 @@ V(1).c()
V(1).d()
# Only keywords should be possible to complete.
#? ['is', 'in', 'not', 'and', 'or', 'if']
V(1).d()
V(1).d()
# -----------------

View File

@@ -73,7 +73,7 @@ def _check_number(Script, source, result='float'):
def test_completion_on_number_literals(Script):
# No completions on an int literal (is a float).
assert [c.name for c in Script('1.').completions()] \
assert [c.name for c in Script('1. ').completions()] \
== ['and', 'if', 'in', 'is', 'not', 'or']
# Multiple points after an int literal basically mean that there's a float
@@ -109,9 +109,12 @@ def test_completion_on_complex_literals(Script):
_check_number(Script, '1j.', 'complex')
_check_number(Script, '44.j.', 'complex')
_check_number(Script, '4.0j.', 'complex')
# No dot no completion - I thought, but 4j is actually a literall after
# No dot no completion - I thought, but 4j is actually a literal after
# which a keyword like or is allowed. Good times, haha!
assert ({c.name for c in Script('4j').completions()} ==
# However this has been disabled again, because it apparently annoyed
# users. So no completion after j without a space :)
assert not Script('4j').completions()
assert ({c.name for c in Script('4j ').completions()} ==
{'if', 'and', 'in', 'is', 'not', 'or'})

View File

@@ -119,7 +119,8 @@ def test_generator(Script):
def test_in_comment(Script):
assert Script(" # Comment").completions()
assert Script("max_attr_value = int(2) # Cast to int for spe").completions()
# TODO this is a bit ugly, that the behaviors in comments are different.
assert not Script("max_attr_value = int(2) # Cast to int for spe").completions()
def test_async(Script, environment):
@@ -140,3 +141,18 @@ def test_async(Script, environment):
def test_with_stmt_error_recovery(Script):
assert Script('with open('') as foo: foo.\na', line=1).completions()
@pytest.mark.parametrize(
'code, has_keywords', (
('', True),
('x;', True),
('1', False),
('1 ', True),
('1\t', True),
('1\n', True),
('1\\\n', True),
)
)
def test_keyword_completion(Script, code, has_keywords):
assert has_keywords == any(x.is_keyword for x in Script(code).completions())