From 463180214d6a1ebf8662d0cfac200b6cca183b63 Mon Sep 17 00:00:00 2001 From: Mubashshir Date: Thu, 19 Nov 2020 22:17:43 +0600 Subject: [PATCH 1/4] fix for gsv4 and new jedi --- gedi.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/gedi.py b/gedi.py index 77fef27..6bdbaa9 100644 --- a/gedi.py +++ b/gedi.py @@ -1,6 +1,7 @@ import os import tempfile import subprocess +import jedi from jedi.api import Script from gi.repository import GObject, Gedit, Gtk, GtkSource @@ -63,7 +64,7 @@ def __init__(self): def do_get_name(self): return _("Gedi Python Code Completion") - + def get_iter_correctly(self, context): if isinstance(context.get_iter(), tuple): return context.get_iter()[1]; @@ -93,17 +94,18 @@ def do_populate(self, context): it = self.get_iter_correctly(context) document = it.get_buffer() proposals = [] - + for completion in Jedi.get_script(document).completions(): complete = completion.name - if jedi.__version__ <= (0,7,0): + if tuple(int(n) for n in jedi.__version__.split('.'))<= (0,7,0): doc=completion.doc else: doc=completion.docstring() - proposals.append(GtkSource.CompletionItem.new(completion.name, - completion.name, - self.get_icon_for_type(completion.type), - doc)) + comp = GtkSource.CompletionItem.new() + comp.props.label = comp.props.text = completion.name + comp.props.icon = self.get_icon_for_type(completion.type) + comp.props.info = doc + proposals.append(comp) context.add_proposals(self, proposals, True) From 9de053fee94a2c49926aa9e12c4a61e6f521388c Mon Sep 17 00:00:00 2001 From: Mubashshir Date: Thu, 19 Nov 2020 23:04:18 +0600 Subject: [PATCH 2/4] Multithreaded implementation --- gedi.py | 83 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 31 deletions(-) diff --git a/gedi.py b/gedi.py index 6bdbaa9..d4e307e 100644 --- a/gedi.py +++ b/gedi.py @@ -4,7 +4,8 @@ import jedi from jedi.api import Script -from gi.repository import GObject, Gedit, Gtk, GtkSource +from gi.repository import GObject, Gedit, Gtk, GtkSource, GLib +from threading import Thread, Event #FIXME: find real icon names icon_names = {'import': '', @@ -56,12 +57,57 @@ def on_document_load(self, document, p3=None, p4=None, p5=0, p6=0): self.completion_provider = None +def get_icon_for_type(_type): + theme = Gtk.IconTheme.get_default() + try: + return theme.load_icon(icon_names[_type.lower()], 16, 0) + except: + try: + return theme.load_icon(Gtk.STOCK_ADD, 16, 0) + except: + return None + +class JediPopulator(Thread): + def __init__(self, provider, context): + Thread.__init__(self) + self._context = context + self._provider = provider + self._document = provider.get_iter_correctly(context).get_buffer() + self._stop_request = Event() + + def run(self): + proposals = [] + try: + for completion in Jedi.get_script(self._document).completions(): + complete = completion.name + if tuple(int(n) for n in jedi.__version__.split('.'))<= (0,7,0): + doc=completion.doc + else: + doc=completion.docstring() + + comp = GtkSource.CompletionItem.new() + comp.props.label = comp.props.text = completion.name + #comp.props.icon = get_icon_for_type(completion.type) + comp.props.info = doc + proposals.append(comp) + except Exception: + self.stop() + + if not self._stop_request.is_set(): + GLib.idle_add(self._context.add_proposals, self._provider, proposals, True) + + def stop(self): + self._stop_request.set() + @property + def stopped(self): + return self._stop_request.is_set() + class GediCompletionProvider(GObject.Object, GtkSource.CompletionProvider): __gtype_name__ = 'GediProvider' def __init__(self): GObject.Object.__init__(self) - + self.thread = None def do_get_name(self): return _("Gedi Python Code Completion") @@ -90,35 +136,10 @@ def do_get_activation(self): return GtkSource.CompletionActivation.INTERACTIVE def do_populate(self, context): - #TODO: do async maybe? - it = self.get_iter_correctly(context) - document = it.get_buffer() - proposals = [] - - for completion in Jedi.get_script(document).completions(): - complete = completion.name - if tuple(int(n) for n in jedi.__version__.split('.'))<= (0,7,0): - doc=completion.doc - else: - doc=completion.docstring() - comp = GtkSource.CompletionItem.new() - comp.props.label = comp.props.text = completion.name - comp.props.icon = self.get_icon_for_type(completion.type) - comp.props.info = doc - proposals.append(comp) - - - context.add_proposals(self, proposals, True) - - def get_icon_for_type(self, _type): - theme = Gtk.IconTheme.get_default() - try: - return theme.load_icon(icon_names[_type.lower()], 16, 0) - except: - try: - return theme.load_icon(Gtk.STOCK_ADD, 16, 0) - except: - return None + if self.thread and not self.thread.stopped: + self.thread.stop() + self.thread = JediPopulator(self, context) + self.thread.start() GObject.type_register(GediCompletionProvider) From 49100876041a6d6ecca4a8534e03209834357089 Mon Sep 17 00:00:00 2001 From: Mubashshir Date: Fri, 20 Nov 2020 09:31:28 +0600 Subject: [PATCH 3/4] hashbang and icon name support --- gedi.py | 70 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/gedi.py b/gedi.py index d4e307e..0cfcbd4 100644 --- a/gedi.py +++ b/gedi.py @@ -7,17 +7,23 @@ from gi.repository import GObject, Gedit, Gtk, GtkSource, GLib from threading import Thread, Event -#FIXME: find real icon names -icon_names = {'import': '', - 'module': '', - 'class': '', - 'function': '', - 'statement': '', - 'param': ''} +# FIXME: find real icon names +icon_names = { + 'module': 'package-x-generic', + 'class': 'folder', + 'instance': 'edit-copy', + 'function': 'insert-object', + 'param': 'insert-link', + 'keyword': 'format-text-bold', + 'property': 'find-location', + 'statement': 'view-continuous', +} + class Jedi: def get_script(document): - doc_text = document.get_text(document.get_start_iter(), document.get_end_iter(), False) + doc_text = document.get_text( + document.get_start_iter(), document.get_end_iter(), False) iter_cursor = document.get_iter_at_mark(document.get_insert()) linenum = iter_cursor.get_line() + 1 charnum = iter_cursor.get_line_index() @@ -27,27 +33,26 @@ def get_script(document): class GediPlugin(GObject.Object, Gedit.ViewActivatable): __gtype_name__ = "GediPlugin" - py_extension = ".py" view = GObject.property(type=Gedit.View) def __init__(self): GObject.Object.__init__(self) self.completion_provider = None + self.conn_id = None def do_activate(self): - print("Gedi is activated.") document = self.view.get_buffer() - document.connect("loaded", self.on_document_load) - - if document.get_uri_for_display().endswith(self.py_extension): - self.completion_provider = GediCompletionProvider() - self.view.get_completion().add_provider(self.completion_provider) + self.conn_id = document.connect("loaded", self.on_document_load) def do_deactivate(self): - print("Gedi is deactivated.") + document = self.view.get_buffer() + if self.conn_id: + document.disconnect(self.conn_id) def on_document_load(self, document, p3=None, p4=None, p5=0, p6=0): - if document.get_uri_for_display().endswith(self.py_extension): + hashbang_line = document.get_iter_at_line( + 0).get_text(document.get_iter_at_line(1)) + if document.props.mime_type == 'text/x-python' or (hashbang_line.startswith('#!/') and hashbang_line.find('python')): if self.completion_provider is None: self.completion_provider = GediCompletionProvider() self.view.get_completion().add_provider(self.completion_provider) @@ -57,16 +62,6 @@ def on_document_load(self, document, p3=None, p4=None, p5=0, p6=0): self.completion_provider = None -def get_icon_for_type(_type): - theme = Gtk.IconTheme.get_default() - try: - return theme.load_icon(icon_names[_type.lower()], 16, 0) - except: - try: - return theme.load_icon(Gtk.STOCK_ADD, 16, 0) - except: - return None - class JediPopulator(Thread): def __init__(self, provider, context): Thread.__init__(self) @@ -80,47 +75,52 @@ def run(self): try: for completion in Jedi.get_script(self._document).completions(): complete = completion.name - if tuple(int(n) for n in jedi.__version__.split('.'))<= (0,7,0): - doc=completion.doc + if tuple(int(n) for n in jedi.__version__.split('.')) <= (0, 7, 0): + doc = completion.doc else: - doc=completion.docstring() + doc = completion.docstring() comp = GtkSource.CompletionItem.new() comp.props.label = comp.props.text = completion.name - #comp.props.icon = get_icon_for_type(completion.type) + comp.props.icon_name = icon_names.get( + completion.type.lower(), 'action-unavailable') comp.props.info = doc proposals.append(comp) except Exception: self.stop() if not self._stop_request.is_set(): - GLib.idle_add(self._context.add_proposals, self._provider, proposals, True) + GLib.idle_add(self._context.add_proposals, + self._provider, proposals, True) def stop(self): - self._stop_request.set() + self._stop_request.set() + @property def stopped(self): return self._stop_request.is_set() + class GediCompletionProvider(GObject.Object, GtkSource.CompletionProvider): __gtype_name__ = 'GediProvider' def __init__(self): GObject.Object.__init__(self) self.thread = None + def do_get_name(self): return _("Gedi Python Code Completion") def get_iter_correctly(self, context): if isinstance(context.get_iter(), tuple): - return context.get_iter()[1]; + return context.get_iter()[1] else: return context.get_iter() def do_match(self, context): iter = self.get_iter_correctly(context) iter.backward_char() - buffer=iter.get_buffer() + buffer = iter.get_buffer() if buffer.get_context_classes_at_iter(iter) != ['no-spell-check']: return False ch = iter.get_char() From aa15abd1a8ead367a016254835caa0702682c4f5 Mon Sep 17 00:00:00 2001 From: Mubashshir Date: Fri, 20 Nov 2020 09:36:47 +0600 Subject: [PATCH 4/4] update version comparison --- gedi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gedi.py b/gedi.py index 0cfcbd4..33b188a 100644 --- a/gedi.py +++ b/gedi.py @@ -75,7 +75,7 @@ def run(self): try: for completion in Jedi.get_script(self._document).completions(): complete = completion.name - if tuple(int(n) for n in jedi.__version__.split('.')) <= (0, 7, 0): + if tuple(map(int,jedi.__version__.split('.'))) <= (0, 7, 0): doc = completion.doc else: doc = completion.docstring()