generated from itdominator/Python-With-Gtk-Template
More work to get LSP functioning. GOTO partially working
This commit is contained in:
parent
27ab95c065
commit
839f4df5ef
@ -55,7 +55,13 @@ class LSPController:
|
||||
if not language or not server_proc: return False
|
||||
|
||||
json_rpc_endpoint = pylspclient.JsonRpcEndpoint(server_proc.stdin, server_proc.stdout)
|
||||
lsp_endpoint = pylspclient.LspEndpoint(json_rpc_endpoint)
|
||||
|
||||
callbacks = {
|
||||
"textDocument/symbolStatus": print,
|
||||
"textDocument/publishDiagnostics": self.blame,
|
||||
}
|
||||
|
||||
lsp_endpoint = pylspclient.LspEndpoint(json_rpc_endpoint, notify_callbacks = callbacks)
|
||||
lsp_client = pylspclient.LspClient(lsp_endpoint)
|
||||
|
||||
self.lsp_clients[language] = lsp_client
|
||||
@ -71,10 +77,18 @@ class LSPController:
|
||||
|
||||
return server_proc
|
||||
|
||||
|
||||
def blame(self, response):
|
||||
for d in response['diagnostics']:
|
||||
if d['severity'] == 1:
|
||||
print(f"An error occurs in {response['uri']} at {d['range']}:")
|
||||
print(f"\t[{d['source']}] {d['message']}")
|
||||
|
||||
|
||||
|
||||
def _shutting_down(self):
|
||||
keys = self.lsp_clients.keys()
|
||||
for key in keys:
|
||||
print(f"LSP Server: ( {key} ) Shutting Down...")
|
||||
self.lsp_clients[key].shutdown()
|
||||
self.lsp_clients[key].exit()
|
||||
|
||||
|
@ -12,6 +12,12 @@ from .lsp_controller import LSPController
|
||||
|
||||
|
||||
|
||||
|
||||
class LSPPliginException(Exception):
|
||||
...
|
||||
|
||||
|
||||
|
||||
class Plugin(PluginBase):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@ -90,6 +96,12 @@ class Plugin(PluginBase):
|
||||
else:
|
||||
self.lsp_client = self.load_lsp_server()
|
||||
|
||||
if self.lsp_client:
|
||||
# Note: textDocument/didClose is actually called from the open api beforehand
|
||||
# to insure no more than one instanmce of a file is opened
|
||||
uri = self._active_src_view.get_current_filepath().get_uri()
|
||||
self.register_opened_file(self._file_type, uri)
|
||||
|
||||
def load_lsp_server(self):
|
||||
command = self.lsp_servers_config[self._file_type]["command"]
|
||||
if command:
|
||||
@ -98,13 +110,11 @@ class Plugin(PluginBase):
|
||||
|
||||
if client_created:
|
||||
return self.lsp_controller.lsp_clients[self._file_type]
|
||||
else:
|
||||
text = f"LSP could not be created for file type: {self._file_type} ..."
|
||||
self._event_system.emit("bubble_message", ("warning", self.name, text,))
|
||||
|
||||
text = f"LSP could not be created for file type: {self._file_type} ..."
|
||||
self._event_system.emit("bubble_message", ("warning", self.name, text,))
|
||||
return None
|
||||
|
||||
|
||||
def _buffer_changed_first_load(self, buffer):
|
||||
if self.lsp_disabled: return
|
||||
|
||||
@ -112,18 +122,73 @@ class Plugin(PluginBase):
|
||||
|
||||
def _buffer_changed(self, buffer):
|
||||
if self.lsp_disabled: return
|
||||
self._do_completion()
|
||||
|
||||
|
||||
def _do_completion(self, is_invoked = False):
|
||||
if self.lsp_disabled: return
|
||||
|
||||
uri = self._active_src_view.get_current_filepath().get_uri()
|
||||
iter = self._buffer.get_iter_at_mark( self._buffer.get_insert() )
|
||||
line = iter.get_line()
|
||||
offset = iter.get_line_offset()
|
||||
trigger = pylspclient.lsp_structs.CompletionTriggerKind.TriggerCharacter
|
||||
_char = iter.get_char()
|
||||
trigger = None
|
||||
|
||||
if _char in [".", " "]:
|
||||
trigger = pylspclient.lsp_structs.CompletionTriggerKind.TriggerCharacter
|
||||
elif is_invoked:
|
||||
trigger = pylspclient.lsp_structs.CompletionTriggerKind.Invoked
|
||||
else:
|
||||
trigger = pylspclient.lsp_structs.CompletionTriggerKind.TriggerForIncompleteCompletions
|
||||
|
||||
result = self.lsp_client.completion(
|
||||
pylspclient.lsp_structs.TextDocumentIdentifier(uri),
|
||||
pylspclient.lsp_structs.Position(line, offset),
|
||||
pylspclient.lsp_structs.CompletionContext(trigger, _char)
|
||||
)
|
||||
|
||||
if result.items:
|
||||
for item in result.items:
|
||||
print(item.label)
|
||||
else:
|
||||
print(result.label)
|
||||
|
||||
def _do_goto(self):
|
||||
if self.lsp_disabled: return
|
||||
|
||||
iter = self._buffer.get_iter_at_mark( self._buffer.get_insert() )
|
||||
line = iter.get_line() + 1
|
||||
offset = iter.get_line_offset() + 1
|
||||
uri = self._active_src_view.get_current_filepath().get_uri()
|
||||
result = self.lsp_client.declaration(pylspclient.lsp_structs.TextDocumentIdentifier(uri), pylspclient.lsp_structs.Position(line, offset))
|
||||
|
||||
print(result)
|
||||
iter = self._buffer.get_iter_at_mark( self._buffer.get_insert() )
|
||||
line = iter.get_line()
|
||||
offset = iter.get_line_offset()
|
||||
uri = self._active_src_view.get_current_filepath().get_uri()
|
||||
results = self.lsp_client.definition(
|
||||
pylspclient.lsp_structs.TextDocumentIdentifier(uri),
|
||||
pylspclient.lsp_structs.Position(line, offset)
|
||||
)
|
||||
|
||||
results = []
|
||||
if len(results) == 1:
|
||||
result = results[0]
|
||||
file = result.uri[7:]
|
||||
line = result.range.end.line
|
||||
message = f"FILE|{file}:{line}"
|
||||
self._event_system.emit("post_file_to_ipc", message)
|
||||
|
||||
def _do_get_implementation(self):
|
||||
if self.lsp_disabled: return
|
||||
results = self.lsp_client.declaration(pylspclient.lsp_structs.TextDocumentIdentifier(uri), pylspclient.lsp_structs.Position(line, offset))
|
||||
|
||||
def register_opened_file(self, language_id = "", uri = ""):
|
||||
if not language_id or not uri: return
|
||||
|
||||
text = open(uri[7:], "r").read()
|
||||
version = 1
|
||||
|
||||
self.lsp_client.didClose(
|
||||
pylspclient.lsp_structs.TextDocumentItem(uri, language_id, version, text)
|
||||
)
|
||||
|
||||
self.lsp_client.didOpen(
|
||||
pylspclient.lsp_structs.TextDocumentItem(uri, language_id, version, text)
|
||||
)
|
@ -95,8 +95,12 @@ class LspClient(object):
|
||||
:param TextDocumentItem textDocument: The document that was opened.
|
||||
"""
|
||||
|
||||
self.lsp_endpoint.send_notification("textDocument/didClose", textDocument = textDocument)
|
||||
return self.lsp_endpoint.send_notification("textDocument/didOpen", textDocument = textDocument)
|
||||
|
||||
def didClose(self, textDocument):
|
||||
return self.lsp_endpoint.send_notification("textDocument/didClose", textDocument = textDocument)
|
||||
|
||||
def didChange(self, textDocument, contentChanges):
|
||||
"""
|
||||
The document change notification is sent from the client to the server to signal changes to a text document.
|
||||
@ -121,6 +125,7 @@ class LspClient(object):
|
||||
"""
|
||||
result_dict = self.lsp_endpoint.call_method( "textDocument/documentSymbol", textDocument=textDocument )
|
||||
|
||||
if not result_dict: return []
|
||||
return [lsp_structs.SymbolInformation(**sym) for sym in result_dict]
|
||||
|
||||
def declaration(self, textDocument, position):
|
||||
@ -142,6 +147,8 @@ class LspClient(object):
|
||||
position = position
|
||||
)
|
||||
|
||||
if not result_dict: return []
|
||||
|
||||
if "uri" in result_dict:
|
||||
return lsp_structs.Location(**result_dict)
|
||||
|
||||
@ -162,6 +169,7 @@ class LspClient(object):
|
||||
position = position
|
||||
)
|
||||
|
||||
if not result_dict: return []
|
||||
return [lsp_structs.Location(**loc) for loc in result_dict]
|
||||
|
||||
def typeDefinition(self, textDocument, position):
|
||||
@ -179,6 +187,7 @@ class LspClient(object):
|
||||
position = position
|
||||
)
|
||||
|
||||
if not result_dict: return []
|
||||
return [lsp_structs.Location(**loc) for loc in result_dict]
|
||||
|
||||
def signatureHelp(self, textDocument, position):
|
||||
@ -195,6 +204,7 @@ class LspClient(object):
|
||||
position = position
|
||||
)
|
||||
|
||||
if not result_dict: return []
|
||||
return lsp_structs.SignatureHelp(**result_dict)
|
||||
|
||||
def completion(self, textDocument, position, context):
|
||||
@ -214,35 +224,13 @@ class LspClient(object):
|
||||
position = position,
|
||||
context = context
|
||||
)
|
||||
if not result_dict: return []
|
||||
|
||||
if "isIncomplete" in result_dict:
|
||||
return lsp_structs.CompletionList(**result_dict)
|
||||
|
||||
return [lsp_structs.CompletionItem(**loc) for loc in result_dict]
|
||||
|
||||
def definition(self, textDocument, position):
|
||||
"""
|
||||
The go to definition request is sent from the client to the server to
|
||||
resolve the declaration location of a symbol at a given text document
|
||||
position.
|
||||
|
||||
The result type LocationLink[] got introduce with version 3.14.0 and
|
||||
depends in the corresponding client capability
|
||||
`clientCapabilities.textDocument.declaration.linkSupport`.
|
||||
|
||||
:param TextDocumentItem textDocument: The text document.
|
||||
:param Position position: The position inside the text document.
|
||||
"""
|
||||
|
||||
result_dict = self.lsp_endpoint.call_method("textDocument/definition",
|
||||
textDocument = textDocument,
|
||||
position = position)
|
||||
|
||||
if "uri" in result_dict:
|
||||
return lsp_structs.Location(**result_dict)
|
||||
|
||||
return [lsp_structs.Location(**l)
|
||||
if "uri" in l else lsp_structs.LinkLocation(**l) for l in result_dict]
|
||||
|
||||
def references(self, textDocument, position):
|
||||
"""
|
||||
The references request is sent from the client to the server to resolve
|
||||
@ -257,4 +245,5 @@ class LspClient(object):
|
||||
textDocument = textDocument,
|
||||
position = position)
|
||||
|
||||
if not result_dict: return []
|
||||
return [lsp_structs.Location(**loc) for loc in result_dict]
|
Loading…
Reference in New Issue
Block a user