Make string additions work for file path completion

With this most simple cases of file path completions should be working now, fixes #493
This commit is contained in:
Dave Halter
2019-08-05 01:42:58 +02:00
parent 45dada9552
commit 8108122347
3 changed files with 46 additions and 8 deletions

View File

@@ -100,9 +100,11 @@ class Completion:
def completions(self): def completions(self):
leaf = self._module_node.get_leaf_for_position(self._position, include_prefixes=True) leaf = self._module_node.get_leaf_for_position(self._position, include_prefixes=True)
string = _extract_string_while_in_string(leaf, self._position) string, start_leaf = _extract_string_while_in_string(leaf, self._position)
if string is not None: if string is not None:
completions = list(file_name_completions(self._evaluator, string, self._like_name)) completions = list(file_name_completions(
self._evaluator, self._module_context, start_leaf, string, self._like_name
))
if completions: if completions:
return completions return completions
@@ -307,15 +309,15 @@ def _extract_string_while_in_string(leaf, position):
match = re.match(r'^\w*(\'{3}|"{3}|\'|")', leaf.value) match = re.match(r'^\w*(\'{3}|"{3}|\'|")', leaf.value)
quote = match.group(1) quote = match.group(1)
if leaf.line == position[0] and position[1] < leaf.column + match.end(): if leaf.line == position[0] and position[1] < leaf.column + match.end():
return None return None, None
if leaf.end_pos[0] == position[0] and position[1] > leaf.end_pos[1] - len(quote): if leaf.end_pos[0] == position[0] and position[1] > leaf.end_pos[1] - len(quote):
return None return None, None
return cut_value_at_position(leaf, position)[match.end():] return cut_value_at_position(leaf, position)[match.end():], leaf
leaves = [] leaves = []
while leaf is not None and leaf.line == position[0]: while leaf is not None and leaf.line == position[0]:
if leaf.type == 'error_leaf' and ('"' in leaf.value or "'" in leaf.value): if leaf.type == 'error_leaf' and ('"' in leaf.value or "'" in leaf.value):
return ''.join(l.get_code() for l in leaves) return ''.join(l.get_code() for l in leaves), leaf
leaves.insert(0, leaf) leaves.insert(0, leaf)
leaf = leaf.get_previous_leaf() leaf = leaf.get_previous_leaf()
return None return None, None

View File

@@ -3,13 +3,15 @@ import os
from jedi._compatibility import FileNotFoundError from jedi._compatibility import FileNotFoundError
from jedi.evaluate.names import AbstractArbitraryName from jedi.evaluate.names import AbstractArbitraryName
from jedi.api import classes from jedi.api import classes
from jedi.evaluate.helpers import get_str_or_none
def file_name_completions(evaluator, string, like_name): def file_name_completions(evaluator, module_context, start_leaf, string, like_name):
base_name = os.path.basename(string) base_name = os.path.basename(string)
like_name = base_name + like_name like_name = base_name + like_name
string = os.path.dirname(string) string = os.path.dirname(string)
string = _get_string_additions(module_context, start_leaf) + string
base_path = os.path.join(evaluator.project._path, string) base_path = os.path.join(evaluator.project._path, string)
try: try:
listed = os.listdir(base_path) listed = os.listdir(base_path)
@@ -29,6 +31,35 @@ def file_name_completions(evaluator, string, like_name):
) )
def _get_string_additions(module_context, start_leaf):
addition = start_leaf.get_previous_leaf()
if addition != '+':
return ''
node = addition.parent
string = ''
was_addition = True
for child_node in reversed(node.children[:node.children.index(addition)]):
if was_addition:
was_addition = False
context = module_context.create_context(node)
contexts = context.eval_node(child_node)
if len(contexts) != 1:
return string
c, = contexts
s = get_str_or_none(c)
if s is None:
return string
string = s + string
continue
if child_node != '+':
break
was_addition = True
child_node
module_context
return string
class FileName(AbstractArbitraryName): class FileName(AbstractArbitraryName):
api_type = u'path' api_type = u'path'
is_context_name = False is_context_name = False

View File

@@ -185,6 +185,11 @@ def test_keyword_completion(Script, code, has_keywords):
('example.py', 'r"""\ntest', None, []), ('example.py', 'r"""\ntest', None, []),
('example.py', 'u"""tes\n', (1, 7), ['t' + s]), ('example.py', 'u"""tes\n', (1, 7), ['t' + s]),
('example.py', '"""test%stest_cache.p"""' % s, 20, ['y']), ('example.py', '"""test%stest_cache.p"""' % s, 20, ['y']),
# Adding
('example.py', '"test" + "%stest_cac' % s, None, ['he.py']),
('example.py', '"test" + "%s" + "test_cac' % s, None, ['he.py']),
('example.py', 'x = 1 + "test', None, [s]),
] ]
) )
def test_file_path_completions(Script, file, code, column, expected): def test_file_path_completions(Script, file, code, column, expected):