Initial display logic of completion request

This commit is contained in:
itdominator 2024-09-16 02:03:16 -05:00
parent 8e615349b7
commit bc47275e57
4 changed files with 160 additions and 60 deletions

View File

@ -1,6 +1,11 @@
# Python imports # Python imports
# Lib 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
# Application imports # Application imports
from libs.dto.lsp_message_structs import LSPResponseTypes, LSPResponseRequest, LSPResponseNotification from libs.dto.lsp_message_structs import LSPResponseTypes, LSPResponseRequest, LSPResponseNotification
@ -39,60 +44,43 @@ class EditorControllerMixin(KeyInputController, EditorEventsMixin):
page_num = None page_num = None
container = None container = None
# logger.debug( repr(message) ) logger.debug( repr(message) )
if isinstance(message, dict): if isinstance(message, dict):
... ...
if isinstance(message, LSPResponseRequest): if hasattr(message, "result"):
keys = message.result.keys() keys = message.result.keys()
if "items" in keys: if "items" in keys:
self.handle_completion(message.result["items"]) buffer = source_view.get_buffer()
completion = source_view.get_completion()
providers = completion.get_providers()
for provider in providers:
if provider.__class__.__name__ == 'LSPCompletionProvider':
# context = completion.create_context( buffer.get_iter_at_mark( buffer.get_insert() ) )
# context = completion.create_context( None )
# provider.do_populate(context, message.result["items"])
box = Gtk.Box()
box.set_homogeneous(True)
# iter = buffer.get_iter_at_mark( buffer.get_insert() )
# rects, recte = source_view.get_cursor_locations(iter)
rect = source_view.get_allocation()
box.set_orientation( Gtk.Orientation.VERTICAL )
for item in message.result["items"]:
box.add( provider.create_completion_item_button(item) )
box.show_all()
source_view.add_child_in_window(box, Gtk.TextWindowType.WIDGET, rect.width - 200, rect.height / 2)
if "result" in keys: if "result" in keys:
... ...
if isinstance(message, LSPResponseNotification): if hasattr(message, "method"):
if message.method == "textDocument/publshDiagnostics": if message.method == "textDocument/publshDiagnostics":
... ...
source_view = None source_view = None
# export const Text = 1;
# export const Method = 2;
# export const Function = 3;
# export const Constructor = 4;
# export const Field = 5;
# export const Variable = 6;
# export const Class = 7;
# export const Interface = 8;
# export const Module = 9;
# export const Property = 10;
# export const Unit = 11;
# export const Value = 12;
# export const Enum = 13;
# export const Keyword = 14;
# export const Snippet = 15;
# export const Color = 16;
# export const File = 17;
# export const Reference = 18;
# export const Folder = 19;
# export const EnumMember = 20;
# export const Constant = 21;
# export const Struct = 22;
# export const Event = 23;
# export const Operator = 24;
# export const TypeParameter = 25;
def handle_completion(self, items):
print()
print()
print()
print(len(items))
print()
print()
print()
for item in items:
if item["kind"] in [2, 3, 4, 5, 6, 7, 8, 10, 15]:
# print(item)
...

View File

@ -0,0 +1,98 @@
# 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
# Application imports
class LSPCompletionProvider(GObject.Object, GtkSource.CompletionProvider):
"""
This code is an LSP code completion plugin for Newton.
# NOTE: Some code pulled/referenced from here --> https://github.com/isamert/gedi
"""
__gtype_name__ = 'LSPProvider'
def __init__(self, source_view):
GObject.Object.__init__(self)
self._theme = Gtk.IconTheme.get_default()
self._source_view = source_view
def do_get_name(self):
return "LSP 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)
buffer = iter.get_buffer()
if buffer.get_context_classes_at_iter(iter) != ['no-spell-check']:
return False
ch = iter.get_char()
# NOTE: Look to re-add or apply supprting logic to use spaces
# As is it slows down the editor in certain contexts...
if not (ch in ('_', '.', ' ') or ch.isalnum()):
# 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, result = None):
result = event_system.emit_and_await("textDocument/completion", (self._source_view,))
proposals = []
if result:
if not result.items is None:
for item in result.items:
proposals.append( self.create_completion_item(item) )
else:
proposals.append( self.create_completion_item(result) )
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
def create_completion_item(self, item):
comp_item = GtkSource.CompletionItem.new()
comp_item.set_label(item.label)
if item.textEdit:
if isinstance(item.textEdit, dict):
comp_item.set_text(item.textEdit["newText"])
else:
comp_item.set_text(item.textEdit)
else:
comp_item.set_text(item.insertText)
comp_item.set_icon( self.get_icon_for_type(item.kind) )
comp_item.set_info(item.documentation)
return comp_item

View File

@ -54,16 +54,13 @@ class LSPCompletionProvider(GObject.Object, GtkSource.CompletionProvider):
def do_get_activation(self): def do_get_activation(self):
return GtkSource.CompletionActivation.INTERACTIVE return GtkSource.CompletionActivation.INTERACTIVE
def do_populate(self, context, result = None): def do_populate(self, context, items = None):
result = event_system.emit_and_await("textDocument/completion", (self._source_view,)) # result = event_system.emit_and_await("textDocument/completion", (self._source_view,))
proposals = [] proposals = []
if result: if items:
if not result.items is None: for item in items:
for item in result.items: proposals.append( self.create_completion_item(item) )
proposals.append( self.create_completion_item(item) )
else:
proposals.append( self.create_completion_item(result) )
context.add_proposals(self, proposals, True) context.add_proposals(self, proposals, True)
@ -80,7 +77,24 @@ class LSPCompletionProvider(GObject.Object, GtkSource.CompletionProvider):
return None return None
def create_completion_item(self, item):
def create_completion_item_button(self, item):
comp_item = Gtk.Box()
button = Gtk.Button(label = item["label"])
keys = item.keys()
if "insertText" in keys:
button.set_tooltip_text( item["insertText"] )
button.set_hexpand(True)
comp_item.add(button)
return comp_item
def _create_completion_item(self, item):
comp_item = GtkSource.CompletionItem.new() comp_item = GtkSource.CompletionItem.new()
comp_item.set_label(item.label) comp_item.set_label(item.label)

View File

@ -11,8 +11,8 @@ from gi.repository import Gio
from gi.repository import GtkSource from gi.repository import GtkSource
# Application imports # Application imports
# from ..custom_completion_providers.lsp_completion_provider import LSPCompletionProvider from ..custom_completion_providers.lsp_completion_provider import LSPCompletionProvider
from ..custom_completion_providers.python_completion_provider import PythonCompletionProvider # from ..custom_completion_providers.python_completion_provider import PythonCompletionProvider
class FileEventsMixin: class FileEventsMixin:
@ -153,8 +153,8 @@ class FileEventsMixin:
word_completion.register(buffer) word_completion.register(buffer)
self._completion.add_provider(word_completion) self._completion.add_provider(word_completion)
# lsp_completion_provider = LSPCompletionProvider(self) lsp_completion_provider = LSPCompletionProvider(self)
# self._completion.add_provider(lsp_completion_provider) self._completion.add_provider(lsp_completion_provider)
# if self._current_filetype in ("python", "python3"): # if self._current_filetype in ("python", "python3"):
# py_lsp_completion_provider = PythonCompletionProvider(uri) # py_lsp_completion_provider = PythonCompletionProvider(uri)