1
0
forked from VimPlug/jedi

Make some file path completions in os.path.join work

This commit is contained in:
Dave Halter
2019-08-07 01:34:46 +02:00
parent 7c1c4981fb
commit 5726c29385
2 changed files with 63 additions and 21 deletions

View File

@@ -10,12 +10,17 @@ def file_name_completions(evaluator, module_context, start_leaf, string, like_na
# First we want to find out what can actually be changed as a name.
like_name_length = len(os.path.basename(string) + like_name)
string = _get_string_additions(module_context, start_leaf) + string
addition = _get_string_additions(module_context, start_leaf)
if addition is None:
return
string = addition + string
# Here we use basename again, because if strings are added like
# `'foo' + 'bar`, it should complete to `foobar/`.
must_start_with = os.path.basename(string) + like_name
string = os.path.dirname(string)
string = _maybe_add_os_path_join(module_context, start_leaf, string)
base_path = os.path.join(evaluator.project._path, string)
try:
listed = os.listdir(base_path)
@@ -36,32 +41,64 @@ def file_name_completions(evaluator, module_context, start_leaf, string, like_na
def _get_string_additions(module_context, start_leaf):
addition = start_leaf.get_previous_leaf()
if addition != '+':
return ''
def iterate_nodes():
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 = force_unicode(s) + string
yield child_node
continue
if child_node != '+':
break
was_addition = True
addition = start_leaf.get_previous_leaf()
if addition != '+':
return ''
return _add_strings(module_context, reversed(list(iterate_nodes())))
def _add_strings(module_context, nodes, add_slash=False):
string = ''
context = None
first = True
for child_node in nodes:
if context is None:
context = module_context.create_context(child_node)
contexts = context.eval_node(child_node)
if len(contexts) != 1:
return None
c, = contexts
s = get_str_or_none(c)
if s is None:
return None
if not first and add_slash:
string += os.path.sep
string += force_unicode(s)
first = False
return string
class FileName(AbstractArbitraryName):
api_type = u'path'
is_context_name = False
def _maybe_add_os_path_join(module_context, start_leaf, string):
arglist = start_leaf.parent
if arglist.type == 'arglist':
trailer = arglist.parent
if trailer.type == 'trailer':
atom = trailer.get_previous_sibling()
if atom.type != 'trailer':
context = module_context.create_context(atom)
contexts = context.eval_node(atom)
if any([c.name.get_qualified_names(include_module_names=True)
!= ('os', 'path', 'join') for c in contexts]):
return string
nodes = arglist.children[:arglist.children.index(start_leaf):2]
return _add_strings(module_context, nodes, add_slash=True)
return string

View File

@@ -194,7 +194,7 @@ os_path = 'from os.path import *\n'
# 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]),
('example.py', 'x = 1 + "test', None, []),
('example.py', 'x = f("te" + "st)', 16, [s]),
('example.py', 'x = f("te" + "st', 16, [s]),
('example.py', 'x = f("te" + "st"', 16, [s]),
@@ -210,6 +210,11 @@ os_path = 'from os.path import *\n'
(f2, os_path + 'dirname(__file__) + "%stest_ca' % s, None, ['che.py']),
(f2, os_path + 'dirname(abspath(__file__)) + sep + "test_ca', None, ['che.py']),
(f2, os_path + 'join(dirname(__file__), "completion") + sep + "basi', None, ['c.py']),
(f2, os_path + 'join(dirname(__file__), "completion", "basi', None, ['c.py']),
(f2, os_path + 'join(dirname(__file__), "completion", "basi)', 43, ['c.py']),
(f2, os_path + 'join(dirname(__file__), "completion", "basi")', 43, ['c.py']),
(f2, os_path + 'join(dirname(__file__), "completion", "basi)', 35, []),
(f2, os_path + 'join(dirname(__file__), "completion", "basi)', 33, ['on']),
]
)
def test_file_path_completions(Script, file, code, column, expected):