Newton_Editor/src/core/widgets/base/sourceview/custom_completion_providers/python_completion_provider.py

106 lines
3.0 KiB
Python

# Python imports
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('GtkSource', '4')
from gi.repository import Gtk
from gi.repository import GtkSource
from gi.repository import GObject
import jedi
from jedi.api import Script
# Application imports
# FIXME: Find real icon names...
icon_names = {
'import': '',
'module': '',
'class': '',
'function': '',
'statement': '',
'param': ''
}
class Jedi:
def get_script(file, doc_text):
return Script(code = doc_text, path = file)
class PythonCompletionProvider(GObject.Object, GtkSource.CompletionProvider):
"""
This code is A python code completion plugin for Newton.
# NOTE: Some code pulled/referenced from here --> https://github.com/isamert/gedi
"""
__gtype_name__ = 'PythonProvider'
def __init__(self, file):
GObject.Object.__init__(self)
self._theme = Gtk.IconTheme.get_default()
self._file = file
def do_get_name(self):
return "Python Code Completion"
def get_iter_correctly(self, context):
return context.get_iter()[1] if isinstance(context.get_iter(), tuple) else context.get_iter()
def do_match(self, context):
iter = self.get_iter_correctly(context)
iter.backward_char()
buffer = iter.get_buffer()
if buffer.get_context_classes_at_iter(iter) != ['no-spell-check']:
return False
ch = iter.get_char()
if not (ch in ('_', '.') or ch.isalnum()):
return False
return True
def do_get_priority(self):
return 1
def do_get_activation(self):
return GtkSource.CompletionActivation.INTERACTIVE
def do_populate(self, context):
# TODO: Maybe convert async?
it = self.get_iter_correctly(context)
buffer = it.get_buffer()
proposals = []
doc_text = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter(), False)
iter_cursor = buffer.get_iter_at_mark(buffer.get_insert())
linenum = iter_cursor.get_line() + 1
charnum = iter_cursor.get_line_index()
def create_generator():
for completion in Jedi.get_script(self._file, doc_text).complete(line = linenum, column = None, fuzzy = False):
comp_item = GtkSource.CompletionItem.new()
comp_item.set_label(completion.name)
comp_item.set_text(completion.name)
comp_item.set_icon(self.get_icon_for_type(completion.type))
comp_item.set_info(completion.docstring())
yield comp_item
for item in create_generator():
proposals.append(item)
context.add_proposals(self, proposals, True)
def get_icon_for_type(self, _type):
try:
return self._theme.load_icon(icon_names[_type.lower()], 16, 0)
except:
try:
return self._theme.load_icon(Gtk.STOCK_ADD, 16, 0)
except:
return None