@@ -180,6 +180,96 @@ private PyObject LookupObject(string name)
180180 }
181181 }
182182 }
183+
184+ /// <summary>
185+ /// Generate completion data for the specified text by relying on the autocomplete from Jedi package.
186+ /// </summary>
187+ /// <param name="code">The code to parse</param>
188+ /// <returns>Return a list of IExternalCodeCompletionData </returns>
189+ private IExternalCodeCompletionData [ ] GetCompletionDataFromJedi ( string code )
190+ {
191+ var items = new List < PythonCodeCompletionDataCore > ( ) ;
192+
193+ try
194+ {
195+ using ( Py . GIL ( ) )
196+ using ( var jediScope = Py . CreateScope ( ) )
197+ {
198+ jediScope . Set ( "code" , code ) ;
199+
200+ string jediSnippet = @"
201+ import jedi
202+
203+ def _no_docs_merge_name_docs(*args, **kwargs):
204+ return str()
205+
206+ jedi.inference.names._merge_name_docs = _no_docs_merge_name_docs
207+
208+ script = jedi.Script(code)
209+ lines = code.split('\n')
210+ line_no = len(lines)
211+ column_no = len(lines[-1])
212+
213+ completions_list = script.complete(line=line_no, column=column_no)
214+
215+ completion_data = []
216+ for c in completions_list:
217+ completion_data.append({
218+ 'name': c.name,
219+ 'type': c.type,
220+ })
221+ " ;
222+
223+ jediScope . Exec ( jediSnippet ) ;
224+
225+ PyObject pyCompletions = jediScope . Get ( "completion_data" ) ;
226+
227+ var completionCandidates = pyCompletions . As < List < Dictionary < string , string > > > ( ) ;
228+
229+ string name = GetLastName ( code ) ;
230+ var completionItems = new List < PythonCodeCompletionDataCore > ( ) ;
231+ foreach ( var item in completionCandidates )
232+ {
233+ string ? member = item . GetValueOrDefault ( "name" ) ;
234+ if ( string . IsNullOrEmpty ( member ) )
235+ continue ;
236+
237+ string ? type = item . GetValueOrDefault ( "type" ) ;
238+ if ( string . IsNullOrEmpty ( type ) )
239+ continue ;
240+
241+ ExternalCodeCompletionType realType = ExternalCodeCompletionType . Field ;
242+ switch ( type . ToLower ( ) )
243+ {
244+ case "module" :
245+ case "namespace" :
246+ realType = ExternalCodeCompletionType . Namespace ;
247+ break ;
248+ case "class" :
249+ realType = ExternalCodeCompletionType . Class ;
250+ break ;
251+ case "function" :
252+ realType = ExternalCodeCompletionType . Method ;
253+ break ;
254+ case "property" :
255+ realType = ExternalCodeCompletionType . Property ;
256+ break ;
257+ case "statement" :
258+ realType = ExternalCodeCompletionType . Field ;
259+ break ;
260+ default :
261+ break ;
262+ }
263+
264+ PythonCodeCompletionDataCore newCompletionItem = new PythonCodeCompletionDataCore ( member , name , false , realType , this ) ;
265+ items . Add ( newCompletionItem ) ;
266+ }
267+ }
268+ }
269+ catch { }
270+
271+ return [ .. items ] ;
272+ }
183273 #endregion
184274
185275 #region PythonCodeCompletionProviderCommon public methods implementations
@@ -261,9 +351,16 @@ public override IExternalCodeCompletionData[] GetCompletionData(string code, boo
261351
262352 // If unable to find matching results and expand was set to false,
263353 // try again using the full namespace (set expand to true)
264- if ( ! items . Any ( ) && ! expand )
354+ if ( ! items . Any ( ) )
265355 {
266- return GetCompletionData ( code , true ) ;
356+ if ( ! expand )
357+ {
358+ return GetCompletionData ( code , true ) ;
359+ }
360+ else
361+ {
362+ return GetCompletionDataFromJedi ( code ) ;
363+ }
267364 }
268365
269366 return items . ToArray ( ) ;
0 commit comments