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
|
if not language or not server_proc: return False
|
||||||
|
|
||||||
json_rpc_endpoint = pylspclient.JsonRpcEndpoint(server_proc.stdin, server_proc.stdout)
|
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)
|
lsp_client = pylspclient.LspClient(lsp_endpoint)
|
||||||
|
|
||||||
self.lsp_clients[language] = lsp_client
|
self.lsp_clients[language] = lsp_client
|
||||||
@ -70,11 +76,19 @@ class LSPController:
|
|||||||
read_pipe.start()
|
read_pipe.start()
|
||||||
|
|
||||||
return server_proc
|
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):
|
def _shutting_down(self):
|
||||||
keys = self.lsp_clients.keys()
|
keys = self.lsp_clients.keys()
|
||||||
for key in keys:
|
for key in keys:
|
||||||
print(f"LSP Server: ( {key} ) Shutting Down...")
|
print(f"LSP Server: ( {key} ) Shutting Down...")
|
||||||
self.lsp_clients[key].shutdown()
|
self.lsp_clients[key].shutdown()
|
||||||
self.lsp_clients[key].exit()
|
self.lsp_clients[key].exit()
|
||||||
|
|
@ -12,6 +12,12 @@ from .lsp_controller import LSPController
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class LSPPliginException(Exception):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Plugin(PluginBase):
|
class Plugin(PluginBase):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@ -90,6 +96,12 @@ class Plugin(PluginBase):
|
|||||||
else:
|
else:
|
||||||
self.lsp_client = self.load_lsp_server()
|
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):
|
def load_lsp_server(self):
|
||||||
command = self.lsp_servers_config[self._file_type]["command"]
|
command = self.lsp_servers_config[self._file_type]["command"]
|
||||||
if command:
|
if command:
|
||||||
@ -98,13 +110,11 @@ class Plugin(PluginBase):
|
|||||||
|
|
||||||
if client_created:
|
if client_created:
|
||||||
return self.lsp_controller.lsp_clients[self._file_type]
|
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
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _buffer_changed_first_load(self, buffer):
|
def _buffer_changed_first_load(self, buffer):
|
||||||
if self.lsp_disabled: return
|
if self.lsp_disabled: return
|
||||||
|
|
||||||
@ -112,18 +122,73 @@ class Plugin(PluginBase):
|
|||||||
|
|
||||||
def _buffer_changed(self, buffer):
|
def _buffer_changed(self, buffer):
|
||||||
if self.lsp_disabled: return
|
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):
|
def _do_goto(self):
|
||||||
if self.lsp_disabled: return
|
if self.lsp_disabled: return
|
||||||
|
|
||||||
iter = self._buffer.get_iter_at_mark( self._buffer.get_insert() )
|
iter = self._buffer.get_iter_at_mark( self._buffer.get_insert() )
|
||||||
line = iter.get_line() + 1
|
line = iter.get_line()
|
||||||
offset = iter.get_line_offset() + 1
|
offset = iter.get_line_offset()
|
||||||
uri = self._active_src_view.get_current_filepath().get_uri()
|
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))
|
results = self.lsp_client.definition(
|
||||||
|
pylspclient.lsp_structs.TextDocumentIdentifier(uri),
|
||||||
print(result)
|
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):
|
def _do_get_implementation(self):
|
||||||
if self.lsp_disabled: return
|
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.
|
: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)
|
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):
|
def didChange(self, textDocument, contentChanges):
|
||||||
"""
|
"""
|
||||||
The document change notification is sent from the client to the server to signal changes to a text document.
|
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 )
|
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]
|
return [lsp_structs.SymbolInformation(**sym) for sym in result_dict]
|
||||||
|
|
||||||
def declaration(self, textDocument, position):
|
def declaration(self, textDocument, position):
|
||||||
@ -142,6 +147,8 @@ class LspClient(object):
|
|||||||
position = position
|
position = position
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not result_dict: return []
|
||||||
|
|
||||||
if "uri" in result_dict:
|
if "uri" in result_dict:
|
||||||
return lsp_structs.Location(**result_dict)
|
return lsp_structs.Location(**result_dict)
|
||||||
|
|
||||||
@ -162,6 +169,7 @@ class LspClient(object):
|
|||||||
position = position
|
position = position
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not result_dict: return []
|
||||||
return [lsp_structs.Location(**loc) for loc in result_dict]
|
return [lsp_structs.Location(**loc) for loc in result_dict]
|
||||||
|
|
||||||
def typeDefinition(self, textDocument, position):
|
def typeDefinition(self, textDocument, position):
|
||||||
@ -179,6 +187,7 @@ class LspClient(object):
|
|||||||
position = position
|
position = position
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not result_dict: return []
|
||||||
return [lsp_structs.Location(**loc) for loc in result_dict]
|
return [lsp_structs.Location(**loc) for loc in result_dict]
|
||||||
|
|
||||||
def signatureHelp(self, textDocument, position):
|
def signatureHelp(self, textDocument, position):
|
||||||
@ -195,6 +204,7 @@ class LspClient(object):
|
|||||||
position = position
|
position = position
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not result_dict: return []
|
||||||
return lsp_structs.SignatureHelp(**result_dict)
|
return lsp_structs.SignatureHelp(**result_dict)
|
||||||
|
|
||||||
def completion(self, textDocument, position, context):
|
def completion(self, textDocument, position, context):
|
||||||
@ -214,35 +224,13 @@ class LspClient(object):
|
|||||||
position = position,
|
position = position,
|
||||||
context = context
|
context = context
|
||||||
)
|
)
|
||||||
|
if not result_dict: return []
|
||||||
|
|
||||||
if "isIncomplete" in result_dict:
|
if "isIncomplete" in result_dict:
|
||||||
return lsp_structs.CompletionList(**result_dict)
|
return lsp_structs.CompletionList(**result_dict)
|
||||||
|
|
||||||
return [lsp_structs.CompletionItem(**loc) for loc in 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):
|
def references(self, textDocument, position):
|
||||||
"""
|
"""
|
||||||
The references request is sent from the client to the server to resolve
|
The references request is sent from the client to the server to resolve
|
||||||
@ -257,4 +245,5 @@ class LspClient(object):
|
|||||||
textDocument = textDocument,
|
textDocument = textDocument,
|
||||||
position = position)
|
position = position)
|
||||||
|
|
||||||
|
if not result_dict: return []
|
||||||
return [lsp_structs.Location(**loc) for loc in result_dict]
|
return [lsp_structs.Location(**loc) for loc in result_dict]
|
Loading…
Reference in New Issue
Block a user