Skip to content

Commit 4da1436

Browse files
zavubGitHub Enterprise
authored andcommitted
DYN-6930: use jedi power when everything else fails (#14)
* use jedi power when everything else fails * remove extra import
1 parent 6b5ae3d commit 4da1436

File tree

3 files changed

+99
-2
lines changed

3 files changed

+99
-2
lines changed

DSPythonNet3/DSPythonNet3CodeCompletionProviderCore.cs

Lines changed: 99 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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();
1.5 MB
Binary file not shown.
101 KB
Binary file not shown.

0 commit comments

Comments
 (0)