@@ -20,12 +20,20 @@ def sorted_definitions(defs):
2020 return sorted (defs , key = lambda x : (x .module_path or '' , x .line or 0 , x .column or 0 ))
2121
2222
23- def get_on_completion_name (lines , position ):
24- line = lines [position [0 ] - 1 ]
25- # The first step of completions is to get the name
26- return re .search (
27- r'(?!\d)\w+$|$' , line [:position [1 ]]
28- ).group (0 )
23+ def get_on_completion_name (module , lines , position ):
24+ leaf = module .get_leaf_for_position (position )
25+ if leaf is None :
26+ return ''
27+ elif leaf .type in ('string' , 'error_leaf' ):
28+ # Completions inside strings are a bit special, we need to parse the
29+ # string.
30+ line = lines [position [0 ] - 1 ]
31+ # The first step of completions is to get the name
32+ return re .search (r'(?!\d)\w+$|$' , line [:position [1 ]]).group (0 )
33+ elif leaf .type not in ('name' , 'keyword' ):
34+ return ''
35+
36+ return leaf .value [:position [1 ] - leaf .start_pos [1 ]]
2937
3038
3139def _get_code (code_lines , start_pos , end_pos ):
@@ -44,71 +52,83 @@ def error_leaf(self):
4452 return self .args [0 ]
4553
4654
55+ def _get_code_for_stack (code_lines , module , position ):
56+ leaf = module .get_leaf_for_position (position , include_prefixes = True )
57+ # It might happen that we're on whitespace or on a comment. This means
58+ # that we would not get the right leaf.
59+ if leaf .start_pos >= position :
60+ try :
61+ leaf = leaf .get_previous_leaf ()
62+ except IndexError :
63+ return u ('' ) # At the beginning of the file.
64+ is_after_newline = leaf .type == 'newline'
65+ while leaf .type == 'newline' :
66+ try :
67+ leaf = leaf .get_previous_leaf ()
68+ except IndexError :
69+ return u ('' )
70+
71+ if leaf .type in ('indent' , 'dedent' ):
72+ return u ('' )
73+ elif leaf .type == 'error_leaf' or leaf .type == 'string' :
74+ # Error leafs cannot be parsed, completion in strings is also
75+ # impossible.
76+ raise OnErrorLeaf (leaf )
77+ else :
78+ if leaf == ';' :
79+ user_stmt = leaf .parent
80+ else :
81+ user_stmt = leaf .get_definition ()
82+ if user_stmt .parent .type == 'simple_stmt' :
83+ user_stmt = user_stmt .parent
84+
85+ if is_after_newline :
86+ if user_stmt .start_pos [1 ] > position [1 ]:
87+ # This means that it's actually a dedent and that means that we
88+ # start without context (part of a suite).
89+ return u ('' )
90+
91+ # This is basically getting the relevant lines.
92+ code = _get_code (code_lines , user_stmt .get_start_pos_of_prefix (), position )
93+ if code .startswith ('pass' ):
94+ import pdb ; pdb .set_trace ()
95+
96+ return code
97+
98+
4799def get_stack_at_position (grammar , code_lines , module , pos ):
48100 """
49101 Returns the possible node names (e.g. import_from, xor_test or yield_stmt).
50102 """
51- user_stmt = module .get_statement_for_position (pos )
52-
53- if user_stmt is not None and user_stmt .type in ('indent' , 'dedent' ):
54- code = u ('' )
55- else :
56- if user_stmt is None :
57- user_stmt = module .get_leaf_for_position (pos , include_prefixes = True )
58- if pos <= user_stmt .start_pos :
59- try :
60- leaf = user_stmt .get_previous_leaf ()
61- except IndexError :
62- pass
63- else :
64- user_stmt = module .get_statement_for_position (leaf .start_pos )
65-
66- if user_stmt .type == 'error_leaf' or user_stmt .type == 'string' :
67- # Error leafs cannot be parsed, completion in strings is also
68- # impossible.
69- raise OnErrorLeaf (user_stmt )
70-
71- start_pos = user_stmt .start_pos
72- if user_stmt .first_leaf () == '@' :
73- # TODO this once again proves that just using user_stmt.get_code
74- # would probably be nicer than _get_code.
75- # Remove the indent to have a statement that is aligned (properties
76- # on the same line as function)
77- start_pos = start_pos [0 ], 0
78-
79- code = _get_code (code_lines , start_pos , pos )
80- if code == ';' :
81- # ; cannot be parsed.
82- code = u ('' )
83-
84- # Remove whitespace at the end. Necessary, because the tokenizer will parse
85- # an error token (there's no new line at the end in our case). This doesn't
86- # alter any truth about the valid tokens at that position.
87- code = code .rstrip ('\t ' )
88- # Remove as many indents from **all** code lines as possible.
89- code = dedent (code )
90-
91103 class EndMarkerReached (Exception ):
92104 pass
93105
94106 def tokenize_without_endmarker (code ):
95107 tokens = tokenize .source_tokens (code , use_exact_op_types = True )
96108 for token_ in tokens :
97- if token_ [ 0 ] == token . ENDMARKER :
109+ if token_ . string == safeword :
98110 raise EndMarkerReached ()
99- elif token_ [ 0 ] == token .DEDENT :
111+ elif token_ . type == token .DEDENT and False :
100112 # Ignore those. Error statements should not contain them, if
101113 # they do it's for cases where an indentation happens and
102114 # before the endmarker we still see them.
103115 pass
104116 else :
105117 yield token_
106118
119+ code = _get_code_for_stack (code_lines , module , pos )
120+ # We use a word to tell Jedi when we have reached the start of the
121+ # completion.
122+ safeword = 'XXX_USER_WANTS_TO_COMPLETE_HERE_WITH_JEDI'
123+ # Remove as many indents from **all** code lines as possible.
124+ code = dedent (code + safeword )
125+
107126 p = parser .Parser (grammar , code , start_parsing = False )
108127 try :
109128 p .parse (tokenizer = tokenize_without_endmarker (code ))
110129 except EndMarkerReached :
111130 return Stack (p .stack )
131+ raise SystemError ("This really shouldn't happen. There's a bug in Jedi." )
112132
113133
114134class Stack (list ):
0 commit comments