1
0
forked from VimPlug/jedi

Get the first dict completions passing

This commit is contained in:
Dave Halter
2019-09-22 11:13:56 +02:00
parent e86a2ec566
commit e8afb46cde
5 changed files with 69 additions and 31 deletions

View File

@@ -10,6 +10,7 @@ from jedi import settings
from jedi.api import classes
from jedi.api import helpers
from jedi.api import keywords
from jedi.api.dicts import completions_for_dicts
from jedi.api.file_name import file_name_completions
from jedi.inference import imports
from jedi.inference.helpers import infer_call_of_leaf, parse_dotted_names
@@ -177,19 +178,20 @@ class Completion:
if not current_line or current_line[-1] in ' \t.;':
completion_names += self._get_keyword_completion_names(allowed_transitions)
nodes = _gather_nodes(stack)
if nodes[-1] == '[' and stack[-1].nonterminal == 'trailer':
bracket = self._module_node.get_leaf_for_position(self._position, include_prefixes=True)
context = self._module_context.create_context(bracket)
values = infer_call_of_leaf(context, bracket.get_previous_leaf())
completion_names += completions_for_dicts(values)
if any(t in allowed_transitions for t in (PythonTokenTypes.NAME,
PythonTokenTypes.INDENT)):
# This means that we actually have to do type inference.
nonterminals = [stack_node.nonterminal for stack_node in stack]
nodes = []
for stack_node in stack:
if stack_node.dfa.from_rule == 'small_stmt':
nodes = []
else:
nodes += stack_node.nodes
if nodes and nodes[-1] in ('as', 'def', 'class'):
# No completions for ``with x as foo`` and ``import x as foo``.
# Also true for defining names as a class or function.
@@ -282,6 +284,16 @@ class Completion:
yield name
def _gather_nodes(stack):
nodes = []
for stack_node in stack:
if stack_node.dfa.from_rule == 'small_stmt':
nodes = []
else:
nodes += stack_node.nodes
return nodes
def _extract_string_while_in_string(leaf, position):
if leaf.type == 'string':
match = re.match(r'^\w*(\'{3}|"{3}|\'|")', leaf.value)

19
jedi/api/dicts.py Normal file
View File

@@ -0,0 +1,19 @@
from jedi.inference.names import AbstractArbitraryName
_sentinel = object()
class F(AbstractArbitraryName):
api_type = u'path'
is_value_name = False
def completions_for_dicts(dicts, literal_string):
for dct in dicts:
if dct.array_type == 'dict':
for key in dct.get_key_values():
dict_key = key.get_safe_value(default=_sentinel)
if dict_key is not _sentinel:
dict_key_str = str(dict_key)
if dict_key_str.startswith(literal_string):
yield F(dct.inference_state, dict_key_str[len(literal_string):])