From d87b95febfd2ded8086a8873626776c6d374e2f6 Mon Sep 17 00:00:00 2001 From: Alex Carney Date: Wed, 14 Aug 2024 19:49:11 +0100 Subject: [PATCH 1/9] feat: generate server methods from lsp types Similarly to the `BaseLanguageClient` this commit now introduces a `BaseLanguageServer` with methods automatically generated from type definitions provided by `lsprotocol` --- pygls/lsp/_base_client.py | 1996 ++++++++++++++++ pygls/lsp/_base_server.py | 444 ++++ pygls/lsp/client.py | 1998 +---------------- pyproject.toml | 4 +- scripts/check_client_is_uptodate.py | 22 +- ...te_client.py => generate_client_server.py} | 160 +- 6 files changed, 2608 insertions(+), 2016 deletions(-) create mode 100644 pygls/lsp/_base_client.py create mode 100644 pygls/lsp/_base_server.py rename scripts/{generate_client.py => generate_client_server.py} (55%) diff --git a/pygls/lsp/_base_client.py b/pygls/lsp/_base_client.py new file mode 100644 index 00000000..5941bd05 --- /dev/null +++ b/pygls/lsp/_base_client.py @@ -0,0 +1,1996 @@ +# GENERATED FROM scripts/generate_client_server.py -- DO NOT EDIT +# flake8: noqa +from concurrent.futures import Future +from lsprotocol import types +from pygls.client import JsonRPCClient +from pygls.protocol import LanguageServerProtocol +from pygls.protocol import default_converter +from typing import Any +from typing import Callable +from typing import Optional +from typing import Sequence +from typing import Union + + +class BaseLanguageClient(JsonRPCClient): + + def __init__( + self, + name: str, + version: str, + protocol_cls=LanguageServerProtocol, + converter_factory=default_converter, + **kwargs, + ): + self.name = name + self.version = version + super().__init__(protocol_cls, converter_factory, **kwargs) + + def call_hierarchy_incoming_calls( + self, + params: types.CallHierarchyIncomingCallsParams, + callback: Optional[Callable[[Optional[Sequence[types.CallHierarchyIncomingCall]]], None]] = None, + ) -> Future: + """Make a :lsp:`callHierarchy/incomingCalls` request. + + A request to resolve the incoming calls for a given `CallHierarchyItem`. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("callHierarchy/incomingCalls", params, callback) + + async def call_hierarchy_incoming_calls_async( + self, + params: types.CallHierarchyIncomingCallsParams, + ) -> Optional[Sequence[types.CallHierarchyIncomingCall]]: + """Make a :lsp:`callHierarchy/incomingCalls` request. + + A request to resolve the incoming calls for a given `CallHierarchyItem`. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("callHierarchy/incomingCalls", params) + + def call_hierarchy_outgoing_calls( + self, + params: types.CallHierarchyOutgoingCallsParams, + callback: Optional[Callable[[Optional[Sequence[types.CallHierarchyOutgoingCall]]], None]] = None, + ) -> Future: + """Make a :lsp:`callHierarchy/outgoingCalls` request. + + A request to resolve the outgoing calls for a given `CallHierarchyItem`. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("callHierarchy/outgoingCalls", params, callback) + + async def call_hierarchy_outgoing_calls_async( + self, + params: types.CallHierarchyOutgoingCallsParams, + ) -> Optional[Sequence[types.CallHierarchyOutgoingCall]]: + """Make a :lsp:`callHierarchy/outgoingCalls` request. + + A request to resolve the outgoing calls for a given `CallHierarchyItem`. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("callHierarchy/outgoingCalls", params) + + def code_action_resolve( + self, + params: types.CodeAction, + callback: Optional[Callable[[types.CodeAction], None]] = None, + ) -> Future: + """Make a :lsp:`codeAction/resolve` request. + + Request to resolve additional information for a given code action.The request's + parameter is of type {@link CodeAction} the response + is of type {@link CodeAction} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("codeAction/resolve", params, callback) + + async def code_action_resolve_async( + self, + params: types.CodeAction, + ) -> types.CodeAction: + """Make a :lsp:`codeAction/resolve` request. + + Request to resolve additional information for a given code action.The request's + parameter is of type {@link CodeAction} the response + is of type {@link CodeAction} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("codeAction/resolve", params) + + def code_lens_resolve( + self, + params: types.CodeLens, + callback: Optional[Callable[[types.CodeLens], None]] = None, + ) -> Future: + """Make a :lsp:`codeLens/resolve` request. + + A request to resolve a command for a given code lens. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("codeLens/resolve", params, callback) + + async def code_lens_resolve_async( + self, + params: types.CodeLens, + ) -> types.CodeLens: + """Make a :lsp:`codeLens/resolve` request. + + A request to resolve a command for a given code lens. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("codeLens/resolve", params) + + def completion_item_resolve( + self, + params: types.CompletionItem, + callback: Optional[Callable[[types.CompletionItem], None]] = None, + ) -> Future: + """Make a :lsp:`completionItem/resolve` request. + + Request to resolve additional information for a given completion item.The request's + parameter is of type {@link CompletionItem} the response + is of type {@link CompletionItem} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("completionItem/resolve", params, callback) + + async def completion_item_resolve_async( + self, + params: types.CompletionItem, + ) -> types.CompletionItem: + """Make a :lsp:`completionItem/resolve` request. + + Request to resolve additional information for a given completion item.The request's + parameter is of type {@link CompletionItem} the response + is of type {@link CompletionItem} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("completionItem/resolve", params) + + def document_link_resolve( + self, + params: types.DocumentLink, + callback: Optional[Callable[[types.DocumentLink], None]] = None, + ) -> Future: + """Make a :lsp:`documentLink/resolve` request. + + Request to resolve additional information for a given document link. The request's + parameter is of type {@link DocumentLink} the response + is of type {@link DocumentLink} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("documentLink/resolve", params, callback) + + async def document_link_resolve_async( + self, + params: types.DocumentLink, + ) -> types.DocumentLink: + """Make a :lsp:`documentLink/resolve` request. + + Request to resolve additional information for a given document link. The request's + parameter is of type {@link DocumentLink} the response + is of type {@link DocumentLink} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("documentLink/resolve", params) + + def initialize( + self, + params: types.InitializeParams, + callback: Optional[Callable[[types.InitializeResult], None]] = None, + ) -> Future: + """Make a :lsp:`initialize` request. + + The initialize request is sent from the client to the server. + It is sent once as the request after starting up the server. + The requests parameter is of type {@link InitializeParams} + the response if of type {@link InitializeResult} of a Thenable that + resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("initialize", params, callback) + + async def initialize_async( + self, + params: types.InitializeParams, + ) -> types.InitializeResult: + """Make a :lsp:`initialize` request. + + The initialize request is sent from the client to the server. + It is sent once as the request after starting up the server. + The requests parameter is of type {@link InitializeParams} + the response if of type {@link InitializeResult} of a Thenable that + resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("initialize", params) + + def inlay_hint_resolve( + self, + params: types.InlayHint, + callback: Optional[Callable[[types.InlayHint], None]] = None, + ) -> Future: + """Make a :lsp:`inlayHint/resolve` request. + + A request to resolve additional properties for an inlay hint. + The request's parameter is of type {@link InlayHint}, the response is + of type {@link InlayHint} or a Thenable that resolves to such. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("inlayHint/resolve", params, callback) + + async def inlay_hint_resolve_async( + self, + params: types.InlayHint, + ) -> types.InlayHint: + """Make a :lsp:`inlayHint/resolve` request. + + A request to resolve additional properties for an inlay hint. + The request's parameter is of type {@link InlayHint}, the response is + of type {@link InlayHint} or a Thenable that resolves to such. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("inlayHint/resolve", params) + + def shutdown( + self, + params: None, + callback: Optional[Callable[[None], None]] = None, + ) -> Future: + """Make a :lsp:`shutdown` request. + + A shutdown request is sent from the client to the server. + It is sent once when the client decides to shutdown the + server. The only notification that is sent after a shutdown request + is the exit event. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("shutdown", params, callback) + + async def shutdown_async( + self, + params: None, + ) -> None: + """Make a :lsp:`shutdown` request. + + A shutdown request is sent from the client to the server. + It is sent once when the client decides to shutdown the + server. The only notification that is sent after a shutdown request + is the exit event. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("shutdown", params) + + def text_document_code_action( + self, + params: types.CodeActionParams, + callback: Optional[Callable[[Optional[Sequence[Union[types.Command, types.CodeAction]]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/codeAction` request. + + A request to provide commands for the given text document and range. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/codeAction", params, callback) + + async def text_document_code_action_async( + self, + params: types.CodeActionParams, + ) -> Optional[Sequence[Union[types.Command, types.CodeAction]]]: + """Make a :lsp:`textDocument/codeAction` request. + + A request to provide commands for the given text document and range. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/codeAction", params) + + def text_document_code_lens( + self, + params: types.CodeLensParams, + callback: Optional[Callable[[Optional[Sequence[types.CodeLens]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/codeLens` request. + + A request to provide code lens for the given text document. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/codeLens", params, callback) + + async def text_document_code_lens_async( + self, + params: types.CodeLensParams, + ) -> Optional[Sequence[types.CodeLens]]: + """Make a :lsp:`textDocument/codeLens` request. + + A request to provide code lens for the given text document. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/codeLens", params) + + def text_document_color_presentation( + self, + params: types.ColorPresentationParams, + callback: Optional[Callable[[Sequence[types.ColorPresentation]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/colorPresentation` request. + + A request to list all presentation for a color. The request's + parameter is of type {@link ColorPresentationParams} the + response is of type {@link ColorInformation ColorInformation[]} or a Thenable + that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/colorPresentation", params, callback) + + async def text_document_color_presentation_async( + self, + params: types.ColorPresentationParams, + ) -> Sequence[types.ColorPresentation]: + """Make a :lsp:`textDocument/colorPresentation` request. + + A request to list all presentation for a color. The request's + parameter is of type {@link ColorPresentationParams} the + response is of type {@link ColorInformation ColorInformation[]} or a Thenable + that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/colorPresentation", params) + + def text_document_completion( + self, + params: types.CompletionParams, + callback: Optional[Callable[[Union[Sequence[types.CompletionItem], types.CompletionList, None]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/completion` request. + + Request to request completion at a given text document position. The request's + parameter is of type {@link TextDocumentPosition} the response + is of type {@link CompletionItem CompletionItem[]} or {@link CompletionList} + or a Thenable that resolves to such. + + The request can delay the computation of the {@link CompletionItem.detail `detail`} + and {@link CompletionItem.documentation `documentation`} properties to the `completionItem/resolve` + request. However, properties that are needed for the initial sorting and filtering, like `sortText`, + `filterText`, `insertText`, and `textEdit`, must not be changed during resolve. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/completion", params, callback) + + async def text_document_completion_async( + self, + params: types.CompletionParams, + ) -> Union[Sequence[types.CompletionItem], types.CompletionList, None]: + """Make a :lsp:`textDocument/completion` request. + + Request to request completion at a given text document position. The request's + parameter is of type {@link TextDocumentPosition} the response + is of type {@link CompletionItem CompletionItem[]} or {@link CompletionList} + or a Thenable that resolves to such. + + The request can delay the computation of the {@link CompletionItem.detail `detail`} + and {@link CompletionItem.documentation `documentation`} properties to the `completionItem/resolve` + request. However, properties that are needed for the initial sorting and filtering, like `sortText`, + `filterText`, `insertText`, and `textEdit`, must not be changed during resolve. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/completion", params) + + def text_document_declaration( + self, + params: types.DeclarationParams, + callback: Optional[Callable[[Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/declaration` request. + + A request to resolve the type definition locations of a symbol at a given text + document position. The request's parameter is of type {@link TextDocumentPositionParams} + the response is of type {@link Declaration} or a typed array of {@link DeclarationLink} + or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/declaration", params, callback) + + async def text_document_declaration_async( + self, + params: types.DeclarationParams, + ) -> Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]: + """Make a :lsp:`textDocument/declaration` request. + + A request to resolve the type definition locations of a symbol at a given text + document position. The request's parameter is of type {@link TextDocumentPositionParams} + the response is of type {@link Declaration} or a typed array of {@link DeclarationLink} + or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/declaration", params) + + def text_document_definition( + self, + params: types.DefinitionParams, + callback: Optional[Callable[[Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/definition` request. + + A request to resolve the definition location of a symbol at a given text + document position. The request's parameter is of type {@link TextDocumentPosition} + the response is of either type {@link Definition} or a typed array of + {@link DefinitionLink} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/definition", params, callback) + + async def text_document_definition_async( + self, + params: types.DefinitionParams, + ) -> Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]: + """Make a :lsp:`textDocument/definition` request. + + A request to resolve the definition location of a symbol at a given text + document position. The request's parameter is of type {@link TextDocumentPosition} + the response is of either type {@link Definition} or a typed array of + {@link DefinitionLink} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/definition", params) + + def text_document_diagnostic( + self, + params: types.DocumentDiagnosticParams, + callback: Optional[Callable[[Union[types.RelatedFullDocumentDiagnosticReport, types.RelatedUnchangedDocumentDiagnosticReport]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/diagnostic` request. + + The document diagnostic request definition. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/diagnostic", params, callback) + + async def text_document_diagnostic_async( + self, + params: types.DocumentDiagnosticParams, + ) -> Union[types.RelatedFullDocumentDiagnosticReport, types.RelatedUnchangedDocumentDiagnosticReport]: + """Make a :lsp:`textDocument/diagnostic` request. + + The document diagnostic request definition. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/diagnostic", params) + + def text_document_document_color( + self, + params: types.DocumentColorParams, + callback: Optional[Callable[[Sequence[types.ColorInformation]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/documentColor` request. + + A request to list all color symbols found in a given text document. The request's + parameter is of type {@link DocumentColorParams} the + response is of type {@link ColorInformation ColorInformation[]} or a Thenable + that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/documentColor", params, callback) + + async def text_document_document_color_async( + self, + params: types.DocumentColorParams, + ) -> Sequence[types.ColorInformation]: + """Make a :lsp:`textDocument/documentColor` request. + + A request to list all color symbols found in a given text document. The request's + parameter is of type {@link DocumentColorParams} the + response is of type {@link ColorInformation ColorInformation[]} or a Thenable + that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/documentColor", params) + + def text_document_document_highlight( + self, + params: types.DocumentHighlightParams, + callback: Optional[Callable[[Optional[Sequence[types.DocumentHighlight]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/documentHighlight` request. + + Request to resolve a {@link DocumentHighlight} for a given + text document position. The request's parameter is of type {@link TextDocumentPosition} + the request response is an array of type {@link DocumentHighlight} + or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/documentHighlight", params, callback) + + async def text_document_document_highlight_async( + self, + params: types.DocumentHighlightParams, + ) -> Optional[Sequence[types.DocumentHighlight]]: + """Make a :lsp:`textDocument/documentHighlight` request. + + Request to resolve a {@link DocumentHighlight} for a given + text document position. The request's parameter is of type {@link TextDocumentPosition} + the request response is an array of type {@link DocumentHighlight} + or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/documentHighlight", params) + + def text_document_document_link( + self, + params: types.DocumentLinkParams, + callback: Optional[Callable[[Optional[Sequence[types.DocumentLink]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/documentLink` request. + + A request to provide document links + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/documentLink", params, callback) + + async def text_document_document_link_async( + self, + params: types.DocumentLinkParams, + ) -> Optional[Sequence[types.DocumentLink]]: + """Make a :lsp:`textDocument/documentLink` request. + + A request to provide document links + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/documentLink", params) + + def text_document_document_symbol( + self, + params: types.DocumentSymbolParams, + callback: Optional[Callable[[Union[Sequence[types.SymbolInformation], Sequence[types.DocumentSymbol], None]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/documentSymbol` request. + + A request to list all symbols found in a given text document. The request's + parameter is of type {@link TextDocumentIdentifier} the + response is of type {@link SymbolInformation SymbolInformation[]} or a Thenable + that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/documentSymbol", params, callback) + + async def text_document_document_symbol_async( + self, + params: types.DocumentSymbolParams, + ) -> Union[Sequence[types.SymbolInformation], Sequence[types.DocumentSymbol], None]: + """Make a :lsp:`textDocument/documentSymbol` request. + + A request to list all symbols found in a given text document. The request's + parameter is of type {@link TextDocumentIdentifier} the + response is of type {@link SymbolInformation SymbolInformation[]} or a Thenable + that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/documentSymbol", params) + + def text_document_folding_range( + self, + params: types.FoldingRangeParams, + callback: Optional[Callable[[Optional[Sequence[types.FoldingRange]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/foldingRange` request. + + A request to provide folding ranges in a document. The request's + parameter is of type {@link FoldingRangeParams}, the + response is of type {@link FoldingRangeList} or a Thenable + that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/foldingRange", params, callback) + + async def text_document_folding_range_async( + self, + params: types.FoldingRangeParams, + ) -> Optional[Sequence[types.FoldingRange]]: + """Make a :lsp:`textDocument/foldingRange` request. + + A request to provide folding ranges in a document. The request's + parameter is of type {@link FoldingRangeParams}, the + response is of type {@link FoldingRangeList} or a Thenable + that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/foldingRange", params) + + def text_document_formatting( + self, + params: types.DocumentFormattingParams, + callback: Optional[Callable[[Optional[Sequence[types.TextEdit]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/formatting` request. + + A request to format a whole document. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/formatting", params, callback) + + async def text_document_formatting_async( + self, + params: types.DocumentFormattingParams, + ) -> Optional[Sequence[types.TextEdit]]: + """Make a :lsp:`textDocument/formatting` request. + + A request to format a whole document. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/formatting", params) + + def text_document_hover( + self, + params: types.HoverParams, + callback: Optional[Callable[[Optional[types.Hover]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/hover` request. + + Request to request hover information at a given text document position. The request's + parameter is of type {@link TextDocumentPosition} the response is of + type {@link Hover} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/hover", params, callback) + + async def text_document_hover_async( + self, + params: types.HoverParams, + ) -> Optional[types.Hover]: + """Make a :lsp:`textDocument/hover` request. + + Request to request hover information at a given text document position. The request's + parameter is of type {@link TextDocumentPosition} the response is of + type {@link Hover} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/hover", params) + + def text_document_implementation( + self, + params: types.ImplementationParams, + callback: Optional[Callable[[Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/implementation` request. + + A request to resolve the implementation locations of a symbol at a given text + document position. The request's parameter is of type {@link TextDocumentPositionParams} + the response is of type {@link Definition} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/implementation", params, callback) + + async def text_document_implementation_async( + self, + params: types.ImplementationParams, + ) -> Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]: + """Make a :lsp:`textDocument/implementation` request. + + A request to resolve the implementation locations of a symbol at a given text + document position. The request's parameter is of type {@link TextDocumentPositionParams} + the response is of type {@link Definition} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/implementation", params) + + def text_document_inlay_hint( + self, + params: types.InlayHintParams, + callback: Optional[Callable[[Optional[Sequence[types.InlayHint]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/inlayHint` request. + + A request to provide inlay hints in a document. The request's parameter is of + type {@link InlayHintsParams}, the response is of type + {@link InlayHint InlayHint[]} or a Thenable that resolves to such. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/inlayHint", params, callback) + + async def text_document_inlay_hint_async( + self, + params: types.InlayHintParams, + ) -> Optional[Sequence[types.InlayHint]]: + """Make a :lsp:`textDocument/inlayHint` request. + + A request to provide inlay hints in a document. The request's parameter is of + type {@link InlayHintsParams}, the response is of type + {@link InlayHint InlayHint[]} or a Thenable that resolves to such. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/inlayHint", params) + + def text_document_inline_completion( + self, + params: types.InlineCompletionParams, + callback: Optional[Callable[[Union[types.InlineCompletionList, Sequence[types.InlineCompletionItem], None]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/inlineCompletion` request. + + A request to provide inline completions in a document. The request's parameter is of + type {@link InlineCompletionParams}, the response is of type + {@link InlineCompletion InlineCompletion[]} or a Thenable that resolves to such. + + @since 3.18.0 + @proposed + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/inlineCompletion", params, callback) + + async def text_document_inline_completion_async( + self, + params: types.InlineCompletionParams, + ) -> Union[types.InlineCompletionList, Sequence[types.InlineCompletionItem], None]: + """Make a :lsp:`textDocument/inlineCompletion` request. + + A request to provide inline completions in a document. The request's parameter is of + type {@link InlineCompletionParams}, the response is of type + {@link InlineCompletion InlineCompletion[]} or a Thenable that resolves to such. + + @since 3.18.0 + @proposed + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/inlineCompletion", params) + + def text_document_inline_value( + self, + params: types.InlineValueParams, + callback: Optional[Callable[[Optional[Sequence[Union[types.InlineValueText, types.InlineValueVariableLookup, types.InlineValueEvaluatableExpression]]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/inlineValue` request. + + A request to provide inline values in a document. The request's parameter is of + type {@link InlineValueParams}, the response is of type + {@link InlineValue InlineValue[]} or a Thenable that resolves to such. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/inlineValue", params, callback) + + async def text_document_inline_value_async( + self, + params: types.InlineValueParams, + ) -> Optional[Sequence[Union[types.InlineValueText, types.InlineValueVariableLookup, types.InlineValueEvaluatableExpression]]]: + """Make a :lsp:`textDocument/inlineValue` request. + + A request to provide inline values in a document. The request's parameter is of + type {@link InlineValueParams}, the response is of type + {@link InlineValue InlineValue[]} or a Thenable that resolves to such. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/inlineValue", params) + + def text_document_linked_editing_range( + self, + params: types.LinkedEditingRangeParams, + callback: Optional[Callable[[Optional[types.LinkedEditingRanges]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/linkedEditingRange` request. + + A request to provide ranges that can be edited together. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/linkedEditingRange", params, callback) + + async def text_document_linked_editing_range_async( + self, + params: types.LinkedEditingRangeParams, + ) -> Optional[types.LinkedEditingRanges]: + """Make a :lsp:`textDocument/linkedEditingRange` request. + + A request to provide ranges that can be edited together. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/linkedEditingRange", params) + + def text_document_moniker( + self, + params: types.MonikerParams, + callback: Optional[Callable[[Optional[Sequence[types.Moniker]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/moniker` request. + + A request to get the moniker of a symbol at a given text document position. + The request parameter is of type {@link TextDocumentPositionParams}. + The response is of type {@link Moniker Moniker[]} or `null`. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/moniker", params, callback) + + async def text_document_moniker_async( + self, + params: types.MonikerParams, + ) -> Optional[Sequence[types.Moniker]]: + """Make a :lsp:`textDocument/moniker` request. + + A request to get the moniker of a symbol at a given text document position. + The request parameter is of type {@link TextDocumentPositionParams}. + The response is of type {@link Moniker Moniker[]} or `null`. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/moniker", params) + + def text_document_on_type_formatting( + self, + params: types.DocumentOnTypeFormattingParams, + callback: Optional[Callable[[Optional[Sequence[types.TextEdit]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/onTypeFormatting` request. + + A request to format a document on type. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/onTypeFormatting", params, callback) + + async def text_document_on_type_formatting_async( + self, + params: types.DocumentOnTypeFormattingParams, + ) -> Optional[Sequence[types.TextEdit]]: + """Make a :lsp:`textDocument/onTypeFormatting` request. + + A request to format a document on type. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/onTypeFormatting", params) + + def text_document_prepare_call_hierarchy( + self, + params: types.CallHierarchyPrepareParams, + callback: Optional[Callable[[Optional[Sequence[types.CallHierarchyItem]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/prepareCallHierarchy` request. + + A request to result a `CallHierarchyItem` in a document at a given position. + Can be used as an input to an incoming or outgoing call hierarchy. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/prepareCallHierarchy", params, callback) + + async def text_document_prepare_call_hierarchy_async( + self, + params: types.CallHierarchyPrepareParams, + ) -> Optional[Sequence[types.CallHierarchyItem]]: + """Make a :lsp:`textDocument/prepareCallHierarchy` request. + + A request to result a `CallHierarchyItem` in a document at a given position. + Can be used as an input to an incoming or outgoing call hierarchy. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/prepareCallHierarchy", params) + + def text_document_prepare_rename( + self, + params: types.PrepareRenameParams, + callback: Optional[Callable[[Union[types.Range, types.PrepareRenamePlaceholder, types.PrepareRenameDefaultBehavior, None]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/prepareRename` request. + + A request to test and perform the setup necessary for a rename. + + @since 3.16 - support for default behavior + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/prepareRename", params, callback) + + async def text_document_prepare_rename_async( + self, + params: types.PrepareRenameParams, + ) -> Union[types.Range, types.PrepareRenamePlaceholder, types.PrepareRenameDefaultBehavior, None]: + """Make a :lsp:`textDocument/prepareRename` request. + + A request to test and perform the setup necessary for a rename. + + @since 3.16 - support for default behavior + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/prepareRename", params) + + def text_document_prepare_type_hierarchy( + self, + params: types.TypeHierarchyPrepareParams, + callback: Optional[Callable[[Optional[Sequence[types.TypeHierarchyItem]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/prepareTypeHierarchy` request. + + A request to result a `TypeHierarchyItem` in a document at a given position. + Can be used as an input to a subtypes or supertypes type hierarchy. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/prepareTypeHierarchy", params, callback) + + async def text_document_prepare_type_hierarchy_async( + self, + params: types.TypeHierarchyPrepareParams, + ) -> Optional[Sequence[types.TypeHierarchyItem]]: + """Make a :lsp:`textDocument/prepareTypeHierarchy` request. + + A request to result a `TypeHierarchyItem` in a document at a given position. + Can be used as an input to a subtypes or supertypes type hierarchy. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/prepareTypeHierarchy", params) + + def text_document_ranges_formatting( + self, + params: types.DocumentRangesFormattingParams, + callback: Optional[Callable[[Optional[Sequence[types.TextEdit]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/rangesFormatting` request. + + A request to format ranges in a document. + + @since 3.18.0 + @proposed + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/rangesFormatting", params, callback) + + async def text_document_ranges_formatting_async( + self, + params: types.DocumentRangesFormattingParams, + ) -> Optional[Sequence[types.TextEdit]]: + """Make a :lsp:`textDocument/rangesFormatting` request. + + A request to format ranges in a document. + + @since 3.18.0 + @proposed + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/rangesFormatting", params) + + def text_document_range_formatting( + self, + params: types.DocumentRangeFormattingParams, + callback: Optional[Callable[[Optional[Sequence[types.TextEdit]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/rangeFormatting` request. + + A request to format a range in a document. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/rangeFormatting", params, callback) + + async def text_document_range_formatting_async( + self, + params: types.DocumentRangeFormattingParams, + ) -> Optional[Sequence[types.TextEdit]]: + """Make a :lsp:`textDocument/rangeFormatting` request. + + A request to format a range in a document. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/rangeFormatting", params) + + def text_document_references( + self, + params: types.ReferenceParams, + callback: Optional[Callable[[Optional[Sequence[types.Location]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/references` request. + + A request to resolve project-wide references for the symbol denoted + by the given text document position. The request's parameter is of + type {@link ReferenceParams} the response is of type + {@link Location Location[]} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/references", params, callback) + + async def text_document_references_async( + self, + params: types.ReferenceParams, + ) -> Optional[Sequence[types.Location]]: + """Make a :lsp:`textDocument/references` request. + + A request to resolve project-wide references for the symbol denoted + by the given text document position. The request's parameter is of + type {@link ReferenceParams} the response is of type + {@link Location Location[]} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/references", params) + + def text_document_rename( + self, + params: types.RenameParams, + callback: Optional[Callable[[Optional[types.WorkspaceEdit]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/rename` request. + + A request to rename a symbol. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/rename", params, callback) + + async def text_document_rename_async( + self, + params: types.RenameParams, + ) -> Optional[types.WorkspaceEdit]: + """Make a :lsp:`textDocument/rename` request. + + A request to rename a symbol. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/rename", params) + + def text_document_selection_range( + self, + params: types.SelectionRangeParams, + callback: Optional[Callable[[Optional[Sequence[types.SelectionRange]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/selectionRange` request. + + A request to provide selection ranges in a document. The request's + parameter is of type {@link SelectionRangeParams}, the + response is of type {@link SelectionRange SelectionRange[]} or a Thenable + that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/selectionRange", params, callback) + + async def text_document_selection_range_async( + self, + params: types.SelectionRangeParams, + ) -> Optional[Sequence[types.SelectionRange]]: + """Make a :lsp:`textDocument/selectionRange` request. + + A request to provide selection ranges in a document. The request's + parameter is of type {@link SelectionRangeParams}, the + response is of type {@link SelectionRange SelectionRange[]} or a Thenable + that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/selectionRange", params) + + def text_document_semantic_tokens_full( + self, + params: types.SemanticTokensParams, + callback: Optional[Callable[[Optional[types.SemanticTokens]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/semanticTokens/full` request. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/semanticTokens/full", params, callback) + + async def text_document_semantic_tokens_full_async( + self, + params: types.SemanticTokensParams, + ) -> Optional[types.SemanticTokens]: + """Make a :lsp:`textDocument/semanticTokens/full` request. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/semanticTokens/full", params) + + def text_document_semantic_tokens_full_delta( + self, + params: types.SemanticTokensDeltaParams, + callback: Optional[Callable[[Union[types.SemanticTokens, types.SemanticTokensDelta, None]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/semanticTokens/full/delta` request. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/semanticTokens/full/delta", params, callback) + + async def text_document_semantic_tokens_full_delta_async( + self, + params: types.SemanticTokensDeltaParams, + ) -> Union[types.SemanticTokens, types.SemanticTokensDelta, None]: + """Make a :lsp:`textDocument/semanticTokens/full/delta` request. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/semanticTokens/full/delta", params) + + def text_document_semantic_tokens_range( + self, + params: types.SemanticTokensRangeParams, + callback: Optional[Callable[[Optional[types.SemanticTokens]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/semanticTokens/range` request. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/semanticTokens/range", params, callback) + + async def text_document_semantic_tokens_range_async( + self, + params: types.SemanticTokensRangeParams, + ) -> Optional[types.SemanticTokens]: + """Make a :lsp:`textDocument/semanticTokens/range` request. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/semanticTokens/range", params) + + def text_document_signature_help( + self, + params: types.SignatureHelpParams, + callback: Optional[Callable[[Optional[types.SignatureHelp]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/signatureHelp` request. + + + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/signatureHelp", params, callback) + + async def text_document_signature_help_async( + self, + params: types.SignatureHelpParams, + ) -> Optional[types.SignatureHelp]: + """Make a :lsp:`textDocument/signatureHelp` request. + + + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/signatureHelp", params) + + def text_document_type_definition( + self, + params: types.TypeDefinitionParams, + callback: Optional[Callable[[Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/typeDefinition` request. + + A request to resolve the type definition locations of a symbol at a given text + document position. The request's parameter is of type {@link TextDocumentPositionParams} + the response is of type {@link Definition} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/typeDefinition", params, callback) + + async def text_document_type_definition_async( + self, + params: types.TypeDefinitionParams, + ) -> Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]: + """Make a :lsp:`textDocument/typeDefinition` request. + + A request to resolve the type definition locations of a symbol at a given text + document position. The request's parameter is of type {@link TextDocumentPositionParams} + the response is of type {@link Definition} or a Thenable that resolves to such. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/typeDefinition", params) + + def text_document_will_save_wait_until( + self, + params: types.WillSaveTextDocumentParams, + callback: Optional[Callable[[Optional[Sequence[types.TextEdit]]], None]] = None, + ) -> Future: + """Make a :lsp:`textDocument/willSaveWaitUntil` request. + + A document will save request is sent from the client to the server before + the document is actually saved. The request can return an array of TextEdits + which will be applied to the text document before it is saved. Please note that + clients might drop results if computing the text edits took too long or if a + server constantly fails on this request. This is done to keep the save fast and + reliable. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("textDocument/willSaveWaitUntil", params, callback) + + async def text_document_will_save_wait_until_async( + self, + params: types.WillSaveTextDocumentParams, + ) -> Optional[Sequence[types.TextEdit]]: + """Make a :lsp:`textDocument/willSaveWaitUntil` request. + + A document will save request is sent from the client to the server before + the document is actually saved. The request can return an array of TextEdits + which will be applied to the text document before it is saved. Please note that + clients might drop results if computing the text edits took too long or if a + server constantly fails on this request. This is done to keep the save fast and + reliable. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("textDocument/willSaveWaitUntil", params) + + def type_hierarchy_subtypes( + self, + params: types.TypeHierarchySubtypesParams, + callback: Optional[Callable[[Optional[Sequence[types.TypeHierarchyItem]]], None]] = None, + ) -> Future: + """Make a :lsp:`typeHierarchy/subtypes` request. + + A request to resolve the subtypes for a given `TypeHierarchyItem`. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("typeHierarchy/subtypes", params, callback) + + async def type_hierarchy_subtypes_async( + self, + params: types.TypeHierarchySubtypesParams, + ) -> Optional[Sequence[types.TypeHierarchyItem]]: + """Make a :lsp:`typeHierarchy/subtypes` request. + + A request to resolve the subtypes for a given `TypeHierarchyItem`. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("typeHierarchy/subtypes", params) + + def type_hierarchy_supertypes( + self, + params: types.TypeHierarchySupertypesParams, + callback: Optional[Callable[[Optional[Sequence[types.TypeHierarchyItem]]], None]] = None, + ) -> Future: + """Make a :lsp:`typeHierarchy/supertypes` request. + + A request to resolve the supertypes for a given `TypeHierarchyItem`. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("typeHierarchy/supertypes", params, callback) + + async def type_hierarchy_supertypes_async( + self, + params: types.TypeHierarchySupertypesParams, + ) -> Optional[Sequence[types.TypeHierarchyItem]]: + """Make a :lsp:`typeHierarchy/supertypes` request. + + A request to resolve the supertypes for a given `TypeHierarchyItem`. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("typeHierarchy/supertypes", params) + + def workspace_diagnostic( + self, + params: types.WorkspaceDiagnosticParams, + callback: Optional[Callable[[types.WorkspaceDiagnosticReport], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/diagnostic` request. + + The workspace diagnostic request definition. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("workspace/diagnostic", params, callback) + + async def workspace_diagnostic_async( + self, + params: types.WorkspaceDiagnosticParams, + ) -> types.WorkspaceDiagnosticReport: + """Make a :lsp:`workspace/diagnostic` request. + + The workspace diagnostic request definition. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("workspace/diagnostic", params) + + def workspace_execute_command( + self, + params: types.ExecuteCommandParams, + callback: Optional[Callable[[Optional[Any]], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/executeCommand` request. + + A request send from the client to the server to execute a command. The request might return + a workspace edit which the client will apply to the workspace. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("workspace/executeCommand", params, callback) + + async def workspace_execute_command_async( + self, + params: types.ExecuteCommandParams, + ) -> Optional[Any]: + """Make a :lsp:`workspace/executeCommand` request. + + A request send from the client to the server to execute a command. The request might return + a workspace edit which the client will apply to the workspace. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("workspace/executeCommand", params) + + def workspace_symbol( + self, + params: types.WorkspaceSymbolParams, + callback: Optional[Callable[[Union[Sequence[types.SymbolInformation], Sequence[types.WorkspaceSymbol], None]], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/symbol` request. + + A request to list project-wide symbols matching the query string given + by the {@link WorkspaceSymbolParams}. The response is + of type {@link SymbolInformation SymbolInformation[]} or a Thenable that + resolves to such. + + @since 3.17.0 - support for WorkspaceSymbol in the returned data. Clients + need to advertise support for WorkspaceSymbols via the client capability + `workspace.symbol.resolveSupport`. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("workspace/symbol", params, callback) + + async def workspace_symbol_async( + self, + params: types.WorkspaceSymbolParams, + ) -> Union[Sequence[types.SymbolInformation], Sequence[types.WorkspaceSymbol], None]: + """Make a :lsp:`workspace/symbol` request. + + A request to list project-wide symbols matching the query string given + by the {@link WorkspaceSymbolParams}. The response is + of type {@link SymbolInformation SymbolInformation[]} or a Thenable that + resolves to such. + + @since 3.17.0 - support for WorkspaceSymbol in the returned data. Clients + need to advertise support for WorkspaceSymbols via the client capability + `workspace.symbol.resolveSupport`. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("workspace/symbol", params) + + def workspace_symbol_resolve( + self, + params: types.WorkspaceSymbol, + callback: Optional[Callable[[types.WorkspaceSymbol], None]] = None, + ) -> Future: + """Make a :lsp:`workspaceSymbol/resolve` request. + + A request to resolve the range inside the workspace + symbol's location. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("workspaceSymbol/resolve", params, callback) + + async def workspace_symbol_resolve_async( + self, + params: types.WorkspaceSymbol, + ) -> types.WorkspaceSymbol: + """Make a :lsp:`workspaceSymbol/resolve` request. + + A request to resolve the range inside the workspace + symbol's location. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("workspaceSymbol/resolve", params) + + def workspace_text_document_content( + self, + params: types.TextDocumentContentParams, + callback: Optional[Callable[[str], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/textDocumentContent` request. + + The `workspace/textDocumentContent` request is sent from the client to the + server to request the content of a text document. + + @since 3.18.0 + @proposed + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("workspace/textDocumentContent", params, callback) + + async def workspace_text_document_content_async( + self, + params: types.TextDocumentContentParams, + ) -> str: + """Make a :lsp:`workspace/textDocumentContent` request. + + The `workspace/textDocumentContent` request is sent from the client to the + server to request the content of a text document. + + @since 3.18.0 + @proposed + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("workspace/textDocumentContent", params) + + def workspace_will_create_files( + self, + params: types.CreateFilesParams, + callback: Optional[Callable[[Optional[types.WorkspaceEdit]], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/willCreateFiles` request. + + The will create files request is sent from the client to the server before files are actually + created as long as the creation is triggered from within the client. + + The request can return a `WorkspaceEdit` which will be applied to workspace before the + files are created. Hence the `WorkspaceEdit` can not manipulate the content of the file + to be created. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("workspace/willCreateFiles", params, callback) + + async def workspace_will_create_files_async( + self, + params: types.CreateFilesParams, + ) -> Optional[types.WorkspaceEdit]: + """Make a :lsp:`workspace/willCreateFiles` request. + + The will create files request is sent from the client to the server before files are actually + created as long as the creation is triggered from within the client. + + The request can return a `WorkspaceEdit` which will be applied to workspace before the + files are created. Hence the `WorkspaceEdit` can not manipulate the content of the file + to be created. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("workspace/willCreateFiles", params) + + def workspace_will_delete_files( + self, + params: types.DeleteFilesParams, + callback: Optional[Callable[[Optional[types.WorkspaceEdit]], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/willDeleteFiles` request. + + The did delete files notification is sent from the client to the server when + files were deleted from within the client. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("workspace/willDeleteFiles", params, callback) + + async def workspace_will_delete_files_async( + self, + params: types.DeleteFilesParams, + ) -> Optional[types.WorkspaceEdit]: + """Make a :lsp:`workspace/willDeleteFiles` request. + + The did delete files notification is sent from the client to the server when + files were deleted from within the client. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("workspace/willDeleteFiles", params) + + def workspace_will_rename_files( + self, + params: types.RenameFilesParams, + callback: Optional[Callable[[Optional[types.WorkspaceEdit]], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/willRenameFiles` request. + + The will rename files request is sent from the client to the server before files are actually + renamed as long as the rename is triggered from within the client. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return self.protocol.send_request("workspace/willRenameFiles", params, callback) + + async def workspace_will_rename_files_async( + self, + params: types.RenameFilesParams, + ) -> Optional[types.WorkspaceEdit]: + """Make a :lsp:`workspace/willRenameFiles` request. + + The will rename files request is sent from the client to the server before files are actually + renamed as long as the rename is triggered from within the client. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + return await self.protocol.send_request_async("workspace/willRenameFiles", params) + + def cancel_request(self, params: types.CancelParams) -> None: + """Send a :lsp:`$/cancelRequest` notification. + + + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("$/cancelRequest", params) + + def exit(self, params: None) -> None: + """Send a :lsp:`exit` notification. + + The exit event is sent from the client to the server to + ask the server to exit its process. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("exit", params) + + def initialized(self, params: types.InitializedParams) -> None: + """Send a :lsp:`initialized` notification. + + The initialized notification is sent from the client to the + server after the client is fully initialized and the server + is allowed to send requests from the server to the client. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("initialized", params) + + def notebook_document_did_change(self, params: types.DidChangeNotebookDocumentParams) -> None: + """Send a :lsp:`notebookDocument/didChange` notification. + + + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("notebookDocument/didChange", params) + + def notebook_document_did_close(self, params: types.DidCloseNotebookDocumentParams) -> None: + """Send a :lsp:`notebookDocument/didClose` notification. + + A notification sent when a notebook closes. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("notebookDocument/didClose", params) + + def notebook_document_did_open(self, params: types.DidOpenNotebookDocumentParams) -> None: + """Send a :lsp:`notebookDocument/didOpen` notification. + + A notification sent when a notebook opens. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("notebookDocument/didOpen", params) + + def notebook_document_did_save(self, params: types.DidSaveNotebookDocumentParams) -> None: + """Send a :lsp:`notebookDocument/didSave` notification. + + A notification sent when a notebook document is saved. + + @since 3.17.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("notebookDocument/didSave", params) + + def progress(self, params: types.ProgressParams) -> None: + """Send a :lsp:`$/progress` notification. + + + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("$/progress", params) + + def set_trace(self, params: types.SetTraceParams) -> None: + """Send a :lsp:`$/setTrace` notification. + + + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("$/setTrace", params) + + def text_document_did_change(self, params: types.DidChangeTextDocumentParams) -> None: + """Send a :lsp:`textDocument/didChange` notification. + + The document change notification is sent from the client to the server to signal + changes to a text document. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("textDocument/didChange", params) + + def text_document_did_close(self, params: types.DidCloseTextDocumentParams) -> None: + """Send a :lsp:`textDocument/didClose` notification. + + The document close notification is sent from the client to the server when + the document got closed in the client. The document's truth now exists where + the document's uri points to (e.g. if the document's uri is a file uri the + truth now exists on disk). As with the open notification the close notification + is about managing the document's content. Receiving a close notification + doesn't mean that the document was open in an editor before. A close + notification requires a previous open notification to be sent. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("textDocument/didClose", params) + + def text_document_did_open(self, params: types.DidOpenTextDocumentParams) -> None: + """Send a :lsp:`textDocument/didOpen` notification. + + The document open notification is sent from the client to the server to signal + newly opened text documents. The document's truth is now managed by the client + and the server must not try to read the document's truth using the document's + uri. Open in this sense means it is managed by the client. It doesn't necessarily + mean that its content is presented in an editor. An open notification must not + be sent more than once without a corresponding close notification send before. + This means open and close notification must be balanced and the max open count + is one. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("textDocument/didOpen", params) + + def text_document_did_save(self, params: types.DidSaveTextDocumentParams) -> None: + """Send a :lsp:`textDocument/didSave` notification. + + The document save notification is sent from the client to the server when + the document got saved in the client. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("textDocument/didSave", params) + + def text_document_will_save(self, params: types.WillSaveTextDocumentParams) -> None: + """Send a :lsp:`textDocument/willSave` notification. + + A document will save notification is sent from the client to the server before + the document is actually saved. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("textDocument/willSave", params) + + def window_work_done_progress_cancel(self, params: types.WorkDoneProgressCancelParams) -> None: + """Send a :lsp:`window/workDoneProgress/cancel` notification. + + The `window/workDoneProgress/cancel` notification is sent from the client to the server to cancel a progress + initiated on the server side. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("window/workDoneProgress/cancel", params) + + def workspace_did_change_configuration(self, params: types.DidChangeConfigurationParams) -> None: + """Send a :lsp:`workspace/didChangeConfiguration` notification. + + The configuration change notification is sent from the client to the server + when the client's configuration has changed. The notification contains + the changed configuration as defined by the language client. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("workspace/didChangeConfiguration", params) + + def workspace_did_change_watched_files(self, params: types.DidChangeWatchedFilesParams) -> None: + """Send a :lsp:`workspace/didChangeWatchedFiles` notification. + + The watched files notification is sent from the client to the server when + the client detects changes to file watched by the language client. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("workspace/didChangeWatchedFiles", params) + + def workspace_did_change_workspace_folders(self, params: types.DidChangeWorkspaceFoldersParams) -> None: + """Send a :lsp:`workspace/didChangeWorkspaceFolders` notification. + + The `workspace/didChangeWorkspaceFolders` notification is sent from the client to the server when the workspace + folder configuration changes. + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("workspace/didChangeWorkspaceFolders", params) + + def workspace_did_create_files(self, params: types.CreateFilesParams) -> None: + """Send a :lsp:`workspace/didCreateFiles` notification. + + The did create files notification is sent from the client to the server when + files were created from within the client. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("workspace/didCreateFiles", params) + + def workspace_did_delete_files(self, params: types.DeleteFilesParams) -> None: + """Send a :lsp:`workspace/didDeleteFiles` notification. + + The will delete files request is sent from the client to the server before files are actually + deleted as long as the deletion is triggered from within the client. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("workspace/didDeleteFiles", params) + + def workspace_did_rename_files(self, params: types.RenameFilesParams) -> None: + """Send a :lsp:`workspace/didRenameFiles` notification. + + The did rename files notification is sent from the client to the server when + files were renamed from within the client. + + @since 3.16.0 + """ + if self.stopped: + raise RuntimeError("Client has been stopped.") + + self.protocol.notify("workspace/didRenameFiles", params) diff --git a/pygls/lsp/_base_server.py b/pygls/lsp/_base_server.py new file mode 100644 index 00000000..e7061396 --- /dev/null +++ b/pygls/lsp/_base_server.py @@ -0,0 +1,444 @@ +# GENERATED FROM scripts/generate_client_server.py -- DO NOT EDIT +# flake8: noqa +from cattrs import Converter +from concurrent.futures import Future +from lsprotocol import types +from pygls.protocol import LanguageServerProtocol +from pygls.protocol import default_converter +from pygls.server import Server +import typing +from typing import Any +from typing import Callable +from typing import Optional +from typing import Sequence +from typing import Type + + +class BaseLanguageServer(Server): + + protocol: LanguageServerProtocol + + def __init__( + self, + protocol_cls: Type[LanguageServerProtocol] = LanguageServerProtocol, + converter_factory: Callable[[], Converter] = default_converter, + loop=None, + **kwargs, + ): + super().__init__(protocol_cls, converter_factory, loop, **kwargs) + + def client_register_capability( + self, + params: types.RegistrationParams, + callback: Optional[Callable[[None], None]] = None, + ) -> Future: + """Make a :lsp:`client/registerCapability` request. + + The `client/registerCapability` request is sent from the server to the client to register a new capability + handler on the client side. + """ + return self.protocol.send_request("client/registerCapability", params, callback) + + async def client_register_capability_async( + self, + params: types.RegistrationParams, + ) -> None: + """Make a :lsp:`client/registerCapability` request. + + The `client/registerCapability` request is sent from the server to the client to register a new capability + handler on the client side. + """ + return await self.protocol.send_request_async("client/registerCapability", params) + + def client_unregister_capability( + self, + params: types.UnregistrationParams, + callback: Optional[Callable[[None], None]] = None, + ) -> Future: + """Make a :lsp:`client/unregisterCapability` request. + + The `client/unregisterCapability` request is sent from the server to the client to unregister a previously registered capability + handler on the client side. + """ + return self.protocol.send_request("client/unregisterCapability", params, callback) + + async def client_unregister_capability_async( + self, + params: types.UnregistrationParams, + ) -> None: + """Make a :lsp:`client/unregisterCapability` request. + + The `client/unregisterCapability` request is sent from the server to the client to unregister a previously registered capability + handler on the client side. + """ + return await self.protocol.send_request_async("client/unregisterCapability", params) + + def window_show_document( + self, + params: types.ShowDocumentParams, + callback: Optional[Callable[[types.ShowDocumentResult], None]] = None, + ) -> Future: + """Make a :lsp:`window/showDocument` request. + + A request to show a document. This request might open an + external program depending on the value of the URI to open. + For example a request to open `https://code.visualstudio.com/` + will very likely open the URI in a WEB browser. + + @since 3.16.0 + """ + return self.protocol.send_request("window/showDocument", params, callback) + + async def window_show_document_async( + self, + params: types.ShowDocumentParams, + ) -> types.ShowDocumentResult: + """Make a :lsp:`window/showDocument` request. + + A request to show a document. This request might open an + external program depending on the value of the URI to open. + For example a request to open `https://code.visualstudio.com/` + will very likely open the URI in a WEB browser. + + @since 3.16.0 + """ + return await self.protocol.send_request_async("window/showDocument", params) + + def window_show_message_request( + self, + params: types.ShowMessageRequestParams, + callback: Optional[Callable[[Optional[types.MessageActionItem]], None]] = None, + ) -> Future: + """Make a :lsp:`window/showMessageRequest` request. + + The show message request is sent from the server to the client to show a message + and a set of options actions to the user. + """ + return self.protocol.send_request("window/showMessageRequest", params, callback) + + async def window_show_message_request_async( + self, + params: types.ShowMessageRequestParams, + ) -> Optional[types.MessageActionItem]: + """Make a :lsp:`window/showMessageRequest` request. + + The show message request is sent from the server to the client to show a message + and a set of options actions to the user. + """ + return await self.protocol.send_request_async("window/showMessageRequest", params) + + def window_work_done_progress_create( + self, + params: types.WorkDoneProgressCreateParams, + callback: Optional[Callable[[None], None]] = None, + ) -> Future: + """Make a :lsp:`window/workDoneProgress/create` request. + + The `window/workDoneProgress/create` request is sent from the server to the client to initiate progress + reporting from the server. + """ + return self.protocol.send_request("window/workDoneProgress/create", params, callback) + + async def window_work_done_progress_create_async( + self, + params: types.WorkDoneProgressCreateParams, + ) -> None: + """Make a :lsp:`window/workDoneProgress/create` request. + + The `window/workDoneProgress/create` request is sent from the server to the client to initiate progress + reporting from the server. + """ + return await self.protocol.send_request_async("window/workDoneProgress/create", params) + + def workspace_apply_edit( + self, + params: types.ApplyWorkspaceEditParams, + callback: Optional[Callable[[types.ApplyWorkspaceEditResult], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/applyEdit` request. + + A request sent from the server to the client to modified certain resources. + """ + return self.protocol.send_request("workspace/applyEdit", params, callback) + + async def workspace_apply_edit_async( + self, + params: types.ApplyWorkspaceEditParams, + ) -> types.ApplyWorkspaceEditResult: + """Make a :lsp:`workspace/applyEdit` request. + + A request sent from the server to the client to modified certain resources. + """ + return await self.protocol.send_request_async("workspace/applyEdit", params) + + def workspace_code_lens_refresh( + self, + params: None, + callback: Optional[Callable[[None], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/codeLens/refresh` request. + + A request to refresh all code actions + + @since 3.16.0 + """ + return self.protocol.send_request("workspace/codeLens/refresh", params, callback) + + async def workspace_code_lens_refresh_async( + self, + params: None, + ) -> None: + """Make a :lsp:`workspace/codeLens/refresh` request. + + A request to refresh all code actions + + @since 3.16.0 + """ + return await self.protocol.send_request_async("workspace/codeLens/refresh", params) + + def workspace_configuration( + self, + params: types.ConfigurationParams, + callback: Optional[Callable[[Sequence[Optional[Any]]], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/configuration` request. + + The 'workspace/configuration' request is sent from the server to the client to fetch a certain + configuration setting. + + This pull model replaces the old push model were the client signaled configuration change via an + event. If the server still needs to react to configuration changes (since the server caches the + result of `workspace/configuration` requests) the server should register for an empty configuration + change event and empty the cache if such an event is received. + """ + return self.protocol.send_request("workspace/configuration", params, callback) + + async def workspace_configuration_async( + self, + params: types.ConfigurationParams, + ) -> Sequence[Optional[Any]]: + """Make a :lsp:`workspace/configuration` request. + + The 'workspace/configuration' request is sent from the server to the client to fetch a certain + configuration setting. + + This pull model replaces the old push model were the client signaled configuration change via an + event. If the server still needs to react to configuration changes (since the server caches the + result of `workspace/configuration` requests) the server should register for an empty configuration + change event and empty the cache if such an event is received. + """ + return await self.protocol.send_request_async("workspace/configuration", params) + + def workspace_diagnostic_refresh( + self, + params: None, + callback: Optional[Callable[[None], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/diagnostic/refresh` request. + + The diagnostic refresh request definition. + + @since 3.17.0 + """ + return self.protocol.send_request("workspace/diagnostic/refresh", params, callback) + + async def workspace_diagnostic_refresh_async( + self, + params: None, + ) -> None: + """Make a :lsp:`workspace/diagnostic/refresh` request. + + The diagnostic refresh request definition. + + @since 3.17.0 + """ + return await self.protocol.send_request_async("workspace/diagnostic/refresh", params) + + def workspace_folding_range_refresh( + self, + params: None, + callback: Optional[Callable[[None], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/foldingRange/refresh` request. + + @since 3.18.0 + @proposed + """ + return self.protocol.send_request("workspace/foldingRange/refresh", params, callback) + + async def workspace_folding_range_refresh_async( + self, + params: None, + ) -> None: + """Make a :lsp:`workspace/foldingRange/refresh` request. + + @since 3.18.0 + @proposed + """ + return await self.protocol.send_request_async("workspace/foldingRange/refresh", params) + + def workspace_inlay_hint_refresh( + self, + params: None, + callback: Optional[Callable[[None], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/inlayHint/refresh` request. + + @since 3.17.0 + """ + return self.protocol.send_request("workspace/inlayHint/refresh", params, callback) + + async def workspace_inlay_hint_refresh_async( + self, + params: None, + ) -> None: + """Make a :lsp:`workspace/inlayHint/refresh` request. + + @since 3.17.0 + """ + return await self.protocol.send_request_async("workspace/inlayHint/refresh", params) + + def workspace_inline_value_refresh( + self, + params: None, + callback: Optional[Callable[[None], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/inlineValue/refresh` request. + + @since 3.17.0 + """ + return self.protocol.send_request("workspace/inlineValue/refresh", params, callback) + + async def workspace_inline_value_refresh_async( + self, + params: None, + ) -> None: + """Make a :lsp:`workspace/inlineValue/refresh` request. + + @since 3.17.0 + """ + return await self.protocol.send_request_async("workspace/inlineValue/refresh", params) + + def workspace_semantic_tokens_refresh( + self, + params: None, + callback: Optional[Callable[[None], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/semanticTokens/refresh` request. + + @since 3.16.0 + """ + return self.protocol.send_request("workspace/semanticTokens/refresh", params, callback) + + async def workspace_semantic_tokens_refresh_async( + self, + params: None, + ) -> None: + """Make a :lsp:`workspace/semanticTokens/refresh` request. + + @since 3.16.0 + """ + return await self.protocol.send_request_async("workspace/semanticTokens/refresh", params) + + def workspace_text_document_content_refresh( + self, + params: types.TextDocumentContentRefreshParams, + callback: Optional[Callable[[None], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/textDocumentContent/refresh` request. + + The `workspace/textDocumentContent` request is sent from the server to the client to refresh + the content of a specific text document. + + @since 3.18.0 + @proposed + """ + return self.protocol.send_request("workspace/textDocumentContent/refresh", params, callback) + + async def workspace_text_document_content_refresh_async( + self, + params: types.TextDocumentContentRefreshParams, + ) -> None: + """Make a :lsp:`workspace/textDocumentContent/refresh` request. + + The `workspace/textDocumentContent` request is sent from the server to the client to refresh + the content of a specific text document. + + @since 3.18.0 + @proposed + """ + return await self.protocol.send_request_async("workspace/textDocumentContent/refresh", params) + + def workspace_workspace_folders( + self, + params: None, + callback: Optional[Callable[[Optional[Sequence[types.WorkspaceFolder]]], None]] = None, + ) -> Future: + """Make a :lsp:`workspace/workspaceFolders` request. + + The `workspace/workspaceFolders` is sent from the server to the client to fetch the open workspace folders. + """ + return self.protocol.send_request("workspace/workspaceFolders", params, callback) + + async def workspace_workspace_folders_async( + self, + params: None, + ) -> Optional[Sequence[types.WorkspaceFolder]]: + """Make a :lsp:`workspace/workspaceFolders` request. + + The `workspace/workspaceFolders` is sent from the server to the client to fetch the open workspace folders. + """ + return await self.protocol.send_request_async("workspace/workspaceFolders", params) + + def cancel_request(self, params: types.CancelParams) -> None: + """Send a :lsp:`$/cancelRequest` notification. + + + """ + self.protocol.notify("$/cancelRequest", params) + + def log_trace(self, params: types.LogTraceParams) -> None: + """Send a :lsp:`$/logTrace` notification. + + + """ + self.protocol.notify("$/logTrace", params) + + def progress(self, params: types.ProgressParams) -> None: + """Send a :lsp:`$/progress` notification. + + + """ + self.protocol.notify("$/progress", params) + + def telemetry_event(self, params: typing.Optional[typing.Any]) -> None: + """Send a :lsp:`telemetry/event` notification. + + The telemetry event notification is sent from the server to the client to ask + the client to log telemetry data. + """ + self.protocol.notify("telemetry/event", params) + + def text_document_publish_diagnostics(self, params: types.PublishDiagnosticsParams) -> None: + """Send a :lsp:`textDocument/publishDiagnostics` notification. + + Diagnostics notification are sent from the server to the client to signal + results of validation runs. + """ + self.protocol.notify("textDocument/publishDiagnostics", params) + + def window_log_message(self, params: types.LogMessageParams) -> None: + """Send a :lsp:`window/logMessage` notification. + + The log message notification is sent from the server to the client to ask + the client to log a particular message. + """ + self.protocol.notify("window/logMessage", params) + + def window_show_message(self, params: types.ShowMessageParams) -> None: + """Send a :lsp:`window/showMessage` notification. + + The show message notification is sent from a server to a client to ask + the client to display a particular message in the user interface. + """ + self.protocol.notify("window/showMessage", params) diff --git a/pygls/lsp/client.py b/pygls/lsp/client.py index 8fe70ae8..c100d348 100644 --- a/pygls/lsp/client.py +++ b/pygls/lsp/client.py @@ -1,1996 +1,6 @@ -# GENERATED FROM scripts/gen-client.py -- DO NOT EDIT -# flake8: noqa -from concurrent.futures import Future -from lsprotocol import types -from pygls.client import JsonRPCClient -from pygls.protocol import LanguageServerProtocol -from pygls.protocol import default_converter -from typing import Any -from typing import Callable -from typing import Optional -from typing import Sequence -from typing import Union +from ._base_client import BaseLanguageClient -class BaseLanguageClient(JsonRPCClient): - - def __init__( - self, - name: str, - version: str, - protocol_cls=LanguageServerProtocol, - converter_factory=default_converter, - **kwargs, - ): - self.name = name - self.version = version - super().__init__(protocol_cls, converter_factory, **kwargs) - - def call_hierarchy_incoming_calls( - self, - params: types.CallHierarchyIncomingCallsParams, - callback: Optional[Callable[[Optional[Sequence[types.CallHierarchyIncomingCall]]], None]] = None, - ) -> Future: - """Make a :lsp:`callHierarchy/incomingCalls` request. - - A request to resolve the incoming calls for a given `CallHierarchyItem`. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("callHierarchy/incomingCalls", params, callback) - - async def call_hierarchy_incoming_calls_async( - self, - params: types.CallHierarchyIncomingCallsParams, - ) -> Optional[Sequence[types.CallHierarchyIncomingCall]]: - """Make a :lsp:`callHierarchy/incomingCalls` request. - - A request to resolve the incoming calls for a given `CallHierarchyItem`. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("callHierarchy/incomingCalls", params) - - def call_hierarchy_outgoing_calls( - self, - params: types.CallHierarchyOutgoingCallsParams, - callback: Optional[Callable[[Optional[Sequence[types.CallHierarchyOutgoingCall]]], None]] = None, - ) -> Future: - """Make a :lsp:`callHierarchy/outgoingCalls` request. - - A request to resolve the outgoing calls for a given `CallHierarchyItem`. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("callHierarchy/outgoingCalls", params, callback) - - async def call_hierarchy_outgoing_calls_async( - self, - params: types.CallHierarchyOutgoingCallsParams, - ) -> Optional[Sequence[types.CallHierarchyOutgoingCall]]: - """Make a :lsp:`callHierarchy/outgoingCalls` request. - - A request to resolve the outgoing calls for a given `CallHierarchyItem`. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("callHierarchy/outgoingCalls", params) - - def code_action_resolve( - self, - params: types.CodeAction, - callback: Optional[Callable[[types.CodeAction], None]] = None, - ) -> Future: - """Make a :lsp:`codeAction/resolve` request. - - Request to resolve additional information for a given code action.The request's - parameter is of type {@link CodeAction} the response - is of type {@link CodeAction} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("codeAction/resolve", params, callback) - - async def code_action_resolve_async( - self, - params: types.CodeAction, - ) -> types.CodeAction: - """Make a :lsp:`codeAction/resolve` request. - - Request to resolve additional information for a given code action.The request's - parameter is of type {@link CodeAction} the response - is of type {@link CodeAction} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("codeAction/resolve", params) - - def code_lens_resolve( - self, - params: types.CodeLens, - callback: Optional[Callable[[types.CodeLens], None]] = None, - ) -> Future: - """Make a :lsp:`codeLens/resolve` request. - - A request to resolve a command for a given code lens. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("codeLens/resolve", params, callback) - - async def code_lens_resolve_async( - self, - params: types.CodeLens, - ) -> types.CodeLens: - """Make a :lsp:`codeLens/resolve` request. - - A request to resolve a command for a given code lens. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("codeLens/resolve", params) - - def completion_item_resolve( - self, - params: types.CompletionItem, - callback: Optional[Callable[[types.CompletionItem], None]] = None, - ) -> Future: - """Make a :lsp:`completionItem/resolve` request. - - Request to resolve additional information for a given completion item.The request's - parameter is of type {@link CompletionItem} the response - is of type {@link CompletionItem} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("completionItem/resolve", params, callback) - - async def completion_item_resolve_async( - self, - params: types.CompletionItem, - ) -> types.CompletionItem: - """Make a :lsp:`completionItem/resolve` request. - - Request to resolve additional information for a given completion item.The request's - parameter is of type {@link CompletionItem} the response - is of type {@link CompletionItem} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("completionItem/resolve", params) - - def document_link_resolve( - self, - params: types.DocumentLink, - callback: Optional[Callable[[types.DocumentLink], None]] = None, - ) -> Future: - """Make a :lsp:`documentLink/resolve` request. - - Request to resolve additional information for a given document link. The request's - parameter is of type {@link DocumentLink} the response - is of type {@link DocumentLink} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("documentLink/resolve", params, callback) - - async def document_link_resolve_async( - self, - params: types.DocumentLink, - ) -> types.DocumentLink: - """Make a :lsp:`documentLink/resolve` request. - - Request to resolve additional information for a given document link. The request's - parameter is of type {@link DocumentLink} the response - is of type {@link DocumentLink} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("documentLink/resolve", params) - - def initialize( - self, - params: types.InitializeParams, - callback: Optional[Callable[[types.InitializeResult], None]] = None, - ) -> Future: - """Make a :lsp:`initialize` request. - - The initialize request is sent from the client to the server. - It is sent once as the request after starting up the server. - The requests parameter is of type {@link InitializeParams} - the response if of type {@link InitializeResult} of a Thenable that - resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("initialize", params, callback) - - async def initialize_async( - self, - params: types.InitializeParams, - ) -> types.InitializeResult: - """Make a :lsp:`initialize` request. - - The initialize request is sent from the client to the server. - It is sent once as the request after starting up the server. - The requests parameter is of type {@link InitializeParams} - the response if of type {@link InitializeResult} of a Thenable that - resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("initialize", params) - - def inlay_hint_resolve( - self, - params: types.InlayHint, - callback: Optional[Callable[[types.InlayHint], None]] = None, - ) -> Future: - """Make a :lsp:`inlayHint/resolve` request. - - A request to resolve additional properties for an inlay hint. - The request's parameter is of type {@link InlayHint}, the response is - of type {@link InlayHint} or a Thenable that resolves to such. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("inlayHint/resolve", params, callback) - - async def inlay_hint_resolve_async( - self, - params: types.InlayHint, - ) -> types.InlayHint: - """Make a :lsp:`inlayHint/resolve` request. - - A request to resolve additional properties for an inlay hint. - The request's parameter is of type {@link InlayHint}, the response is - of type {@link InlayHint} or a Thenable that resolves to such. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("inlayHint/resolve", params) - - def shutdown( - self, - params: None, - callback: Optional[Callable[[None], None]] = None, - ) -> Future: - """Make a :lsp:`shutdown` request. - - A shutdown request is sent from the client to the server. - It is sent once when the client decides to shutdown the - server. The only notification that is sent after a shutdown request - is the exit event. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("shutdown", params, callback) - - async def shutdown_async( - self, - params: None, - ) -> None: - """Make a :lsp:`shutdown` request. - - A shutdown request is sent from the client to the server. - It is sent once when the client decides to shutdown the - server. The only notification that is sent after a shutdown request - is the exit event. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("shutdown", params) - - def text_document_code_action( - self, - params: types.CodeActionParams, - callback: Optional[Callable[[Optional[Sequence[Union[types.Command, types.CodeAction]]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/codeAction` request. - - A request to provide commands for the given text document and range. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/codeAction", params, callback) - - async def text_document_code_action_async( - self, - params: types.CodeActionParams, - ) -> Optional[Sequence[Union[types.Command, types.CodeAction]]]: - """Make a :lsp:`textDocument/codeAction` request. - - A request to provide commands for the given text document and range. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/codeAction", params) - - def text_document_code_lens( - self, - params: types.CodeLensParams, - callback: Optional[Callable[[Optional[Sequence[types.CodeLens]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/codeLens` request. - - A request to provide code lens for the given text document. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/codeLens", params, callback) - - async def text_document_code_lens_async( - self, - params: types.CodeLensParams, - ) -> Optional[Sequence[types.CodeLens]]: - """Make a :lsp:`textDocument/codeLens` request. - - A request to provide code lens for the given text document. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/codeLens", params) - - def text_document_color_presentation( - self, - params: types.ColorPresentationParams, - callback: Optional[Callable[[Sequence[types.ColorPresentation]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/colorPresentation` request. - - A request to list all presentation for a color. The request's - parameter is of type {@link ColorPresentationParams} the - response is of type {@link ColorInformation ColorInformation[]} or a Thenable - that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/colorPresentation", params, callback) - - async def text_document_color_presentation_async( - self, - params: types.ColorPresentationParams, - ) -> Sequence[types.ColorPresentation]: - """Make a :lsp:`textDocument/colorPresentation` request. - - A request to list all presentation for a color. The request's - parameter is of type {@link ColorPresentationParams} the - response is of type {@link ColorInformation ColorInformation[]} or a Thenable - that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/colorPresentation", params) - - def text_document_completion( - self, - params: types.CompletionParams, - callback: Optional[Callable[[Union[Sequence[types.CompletionItem], types.CompletionList, None]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/completion` request. - - Request to request completion at a given text document position. The request's - parameter is of type {@link TextDocumentPosition} the response - is of type {@link CompletionItem CompletionItem[]} or {@link CompletionList} - or a Thenable that resolves to such. - - The request can delay the computation of the {@link CompletionItem.detail `detail`} - and {@link CompletionItem.documentation `documentation`} properties to the `completionItem/resolve` - request. However, properties that are needed for the initial sorting and filtering, like `sortText`, - `filterText`, `insertText`, and `textEdit`, must not be changed during resolve. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/completion", params, callback) - - async def text_document_completion_async( - self, - params: types.CompletionParams, - ) -> Union[Sequence[types.CompletionItem], types.CompletionList, None]: - """Make a :lsp:`textDocument/completion` request. - - Request to request completion at a given text document position. The request's - parameter is of type {@link TextDocumentPosition} the response - is of type {@link CompletionItem CompletionItem[]} or {@link CompletionList} - or a Thenable that resolves to such. - - The request can delay the computation of the {@link CompletionItem.detail `detail`} - and {@link CompletionItem.documentation `documentation`} properties to the `completionItem/resolve` - request. However, properties that are needed for the initial sorting and filtering, like `sortText`, - `filterText`, `insertText`, and `textEdit`, must not be changed during resolve. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/completion", params) - - def text_document_declaration( - self, - params: types.DeclarationParams, - callback: Optional[Callable[[Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/declaration` request. - - A request to resolve the type definition locations of a symbol at a given text - document position. The request's parameter is of type {@link TextDocumentPositionParams} - the response is of type {@link Declaration} or a typed array of {@link DeclarationLink} - or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/declaration", params, callback) - - async def text_document_declaration_async( - self, - params: types.DeclarationParams, - ) -> Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]: - """Make a :lsp:`textDocument/declaration` request. - - A request to resolve the type definition locations of a symbol at a given text - document position. The request's parameter is of type {@link TextDocumentPositionParams} - the response is of type {@link Declaration} or a typed array of {@link DeclarationLink} - or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/declaration", params) - - def text_document_definition( - self, - params: types.DefinitionParams, - callback: Optional[Callable[[Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/definition` request. - - A request to resolve the definition location of a symbol at a given text - document position. The request's parameter is of type {@link TextDocumentPosition} - the response is of either type {@link Definition} or a typed array of - {@link DefinitionLink} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/definition", params, callback) - - async def text_document_definition_async( - self, - params: types.DefinitionParams, - ) -> Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]: - """Make a :lsp:`textDocument/definition` request. - - A request to resolve the definition location of a symbol at a given text - document position. The request's parameter is of type {@link TextDocumentPosition} - the response is of either type {@link Definition} or a typed array of - {@link DefinitionLink} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/definition", params) - - def text_document_diagnostic( - self, - params: types.DocumentDiagnosticParams, - callback: Optional[Callable[[Union[types.RelatedFullDocumentDiagnosticReport, types.RelatedUnchangedDocumentDiagnosticReport]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/diagnostic` request. - - The document diagnostic request definition. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/diagnostic", params, callback) - - async def text_document_diagnostic_async( - self, - params: types.DocumentDiagnosticParams, - ) -> Union[types.RelatedFullDocumentDiagnosticReport, types.RelatedUnchangedDocumentDiagnosticReport]: - """Make a :lsp:`textDocument/diagnostic` request. - - The document diagnostic request definition. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/diagnostic", params) - - def text_document_document_color( - self, - params: types.DocumentColorParams, - callback: Optional[Callable[[Sequence[types.ColorInformation]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/documentColor` request. - - A request to list all color symbols found in a given text document. The request's - parameter is of type {@link DocumentColorParams} the - response is of type {@link ColorInformation ColorInformation[]} or a Thenable - that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/documentColor", params, callback) - - async def text_document_document_color_async( - self, - params: types.DocumentColorParams, - ) -> Sequence[types.ColorInformation]: - """Make a :lsp:`textDocument/documentColor` request. - - A request to list all color symbols found in a given text document. The request's - parameter is of type {@link DocumentColorParams} the - response is of type {@link ColorInformation ColorInformation[]} or a Thenable - that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/documentColor", params) - - def text_document_document_highlight( - self, - params: types.DocumentHighlightParams, - callback: Optional[Callable[[Optional[Sequence[types.DocumentHighlight]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/documentHighlight` request. - - Request to resolve a {@link DocumentHighlight} for a given - text document position. The request's parameter is of type {@link TextDocumentPosition} - the request response is an array of type {@link DocumentHighlight} - or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/documentHighlight", params, callback) - - async def text_document_document_highlight_async( - self, - params: types.DocumentHighlightParams, - ) -> Optional[Sequence[types.DocumentHighlight]]: - """Make a :lsp:`textDocument/documentHighlight` request. - - Request to resolve a {@link DocumentHighlight} for a given - text document position. The request's parameter is of type {@link TextDocumentPosition} - the request response is an array of type {@link DocumentHighlight} - or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/documentHighlight", params) - - def text_document_document_link( - self, - params: types.DocumentLinkParams, - callback: Optional[Callable[[Optional[Sequence[types.DocumentLink]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/documentLink` request. - - A request to provide document links - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/documentLink", params, callback) - - async def text_document_document_link_async( - self, - params: types.DocumentLinkParams, - ) -> Optional[Sequence[types.DocumentLink]]: - """Make a :lsp:`textDocument/documentLink` request. - - A request to provide document links - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/documentLink", params) - - def text_document_document_symbol( - self, - params: types.DocumentSymbolParams, - callback: Optional[Callable[[Union[Sequence[types.SymbolInformation], Sequence[types.DocumentSymbol], None]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/documentSymbol` request. - - A request to list all symbols found in a given text document. The request's - parameter is of type {@link TextDocumentIdentifier} the - response is of type {@link SymbolInformation SymbolInformation[]} or a Thenable - that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/documentSymbol", params, callback) - - async def text_document_document_symbol_async( - self, - params: types.DocumentSymbolParams, - ) -> Union[Sequence[types.SymbolInformation], Sequence[types.DocumentSymbol], None]: - """Make a :lsp:`textDocument/documentSymbol` request. - - A request to list all symbols found in a given text document. The request's - parameter is of type {@link TextDocumentIdentifier} the - response is of type {@link SymbolInformation SymbolInformation[]} or a Thenable - that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/documentSymbol", params) - - def text_document_folding_range( - self, - params: types.FoldingRangeParams, - callback: Optional[Callable[[Optional[Sequence[types.FoldingRange]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/foldingRange` request. - - A request to provide folding ranges in a document. The request's - parameter is of type {@link FoldingRangeParams}, the - response is of type {@link FoldingRangeList} or a Thenable - that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/foldingRange", params, callback) - - async def text_document_folding_range_async( - self, - params: types.FoldingRangeParams, - ) -> Optional[Sequence[types.FoldingRange]]: - """Make a :lsp:`textDocument/foldingRange` request. - - A request to provide folding ranges in a document. The request's - parameter is of type {@link FoldingRangeParams}, the - response is of type {@link FoldingRangeList} or a Thenable - that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/foldingRange", params) - - def text_document_formatting( - self, - params: types.DocumentFormattingParams, - callback: Optional[Callable[[Optional[Sequence[types.TextEdit]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/formatting` request. - - A request to format a whole document. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/formatting", params, callback) - - async def text_document_formatting_async( - self, - params: types.DocumentFormattingParams, - ) -> Optional[Sequence[types.TextEdit]]: - """Make a :lsp:`textDocument/formatting` request. - - A request to format a whole document. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/formatting", params) - - def text_document_hover( - self, - params: types.HoverParams, - callback: Optional[Callable[[Optional[types.Hover]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/hover` request. - - Request to request hover information at a given text document position. The request's - parameter is of type {@link TextDocumentPosition} the response is of - type {@link Hover} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/hover", params, callback) - - async def text_document_hover_async( - self, - params: types.HoverParams, - ) -> Optional[types.Hover]: - """Make a :lsp:`textDocument/hover` request. - - Request to request hover information at a given text document position. The request's - parameter is of type {@link TextDocumentPosition} the response is of - type {@link Hover} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/hover", params) - - def text_document_implementation( - self, - params: types.ImplementationParams, - callback: Optional[Callable[[Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/implementation` request. - - A request to resolve the implementation locations of a symbol at a given text - document position. The request's parameter is of type {@link TextDocumentPositionParams} - the response is of type {@link Definition} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/implementation", params, callback) - - async def text_document_implementation_async( - self, - params: types.ImplementationParams, - ) -> Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]: - """Make a :lsp:`textDocument/implementation` request. - - A request to resolve the implementation locations of a symbol at a given text - document position. The request's parameter is of type {@link TextDocumentPositionParams} - the response is of type {@link Definition} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/implementation", params) - - def text_document_inlay_hint( - self, - params: types.InlayHintParams, - callback: Optional[Callable[[Optional[Sequence[types.InlayHint]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/inlayHint` request. - - A request to provide inlay hints in a document. The request's parameter is of - type {@link InlayHintsParams}, the response is of type - {@link InlayHint InlayHint[]} or a Thenable that resolves to such. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/inlayHint", params, callback) - - async def text_document_inlay_hint_async( - self, - params: types.InlayHintParams, - ) -> Optional[Sequence[types.InlayHint]]: - """Make a :lsp:`textDocument/inlayHint` request. - - A request to provide inlay hints in a document. The request's parameter is of - type {@link InlayHintsParams}, the response is of type - {@link InlayHint InlayHint[]} or a Thenable that resolves to such. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/inlayHint", params) - - def text_document_inline_completion( - self, - params: types.InlineCompletionParams, - callback: Optional[Callable[[Union[types.InlineCompletionList, Sequence[types.InlineCompletionItem], None]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/inlineCompletion` request. - - A request to provide inline completions in a document. The request's parameter is of - type {@link InlineCompletionParams}, the response is of type - {@link InlineCompletion InlineCompletion[]} or a Thenable that resolves to such. - - @since 3.18.0 - @proposed - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/inlineCompletion", params, callback) - - async def text_document_inline_completion_async( - self, - params: types.InlineCompletionParams, - ) -> Union[types.InlineCompletionList, Sequence[types.InlineCompletionItem], None]: - """Make a :lsp:`textDocument/inlineCompletion` request. - - A request to provide inline completions in a document. The request's parameter is of - type {@link InlineCompletionParams}, the response is of type - {@link InlineCompletion InlineCompletion[]} or a Thenable that resolves to such. - - @since 3.18.0 - @proposed - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/inlineCompletion", params) - - def text_document_inline_value( - self, - params: types.InlineValueParams, - callback: Optional[Callable[[Optional[Sequence[Union[types.InlineValueText, types.InlineValueVariableLookup, types.InlineValueEvaluatableExpression]]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/inlineValue` request. - - A request to provide inline values in a document. The request's parameter is of - type {@link InlineValueParams}, the response is of type - {@link InlineValue InlineValue[]} or a Thenable that resolves to such. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/inlineValue", params, callback) - - async def text_document_inline_value_async( - self, - params: types.InlineValueParams, - ) -> Optional[Sequence[Union[types.InlineValueText, types.InlineValueVariableLookup, types.InlineValueEvaluatableExpression]]]: - """Make a :lsp:`textDocument/inlineValue` request. - - A request to provide inline values in a document. The request's parameter is of - type {@link InlineValueParams}, the response is of type - {@link InlineValue InlineValue[]} or a Thenable that resolves to such. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/inlineValue", params) - - def text_document_linked_editing_range( - self, - params: types.LinkedEditingRangeParams, - callback: Optional[Callable[[Optional[types.LinkedEditingRanges]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/linkedEditingRange` request. - - A request to provide ranges that can be edited together. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/linkedEditingRange", params, callback) - - async def text_document_linked_editing_range_async( - self, - params: types.LinkedEditingRangeParams, - ) -> Optional[types.LinkedEditingRanges]: - """Make a :lsp:`textDocument/linkedEditingRange` request. - - A request to provide ranges that can be edited together. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/linkedEditingRange", params) - - def text_document_moniker( - self, - params: types.MonikerParams, - callback: Optional[Callable[[Optional[Sequence[types.Moniker]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/moniker` request. - - A request to get the moniker of a symbol at a given text document position. - The request parameter is of type {@link TextDocumentPositionParams}. - The response is of type {@link Moniker Moniker[]} or `null`. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/moniker", params, callback) - - async def text_document_moniker_async( - self, - params: types.MonikerParams, - ) -> Optional[Sequence[types.Moniker]]: - """Make a :lsp:`textDocument/moniker` request. - - A request to get the moniker of a symbol at a given text document position. - The request parameter is of type {@link TextDocumentPositionParams}. - The response is of type {@link Moniker Moniker[]} or `null`. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/moniker", params) - - def text_document_on_type_formatting( - self, - params: types.DocumentOnTypeFormattingParams, - callback: Optional[Callable[[Optional[Sequence[types.TextEdit]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/onTypeFormatting` request. - - A request to format a document on type. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/onTypeFormatting", params, callback) - - async def text_document_on_type_formatting_async( - self, - params: types.DocumentOnTypeFormattingParams, - ) -> Optional[Sequence[types.TextEdit]]: - """Make a :lsp:`textDocument/onTypeFormatting` request. - - A request to format a document on type. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/onTypeFormatting", params) - - def text_document_prepare_call_hierarchy( - self, - params: types.CallHierarchyPrepareParams, - callback: Optional[Callable[[Optional[Sequence[types.CallHierarchyItem]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/prepareCallHierarchy` request. - - A request to result a `CallHierarchyItem` in a document at a given position. - Can be used as an input to an incoming or outgoing call hierarchy. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/prepareCallHierarchy", params, callback) - - async def text_document_prepare_call_hierarchy_async( - self, - params: types.CallHierarchyPrepareParams, - ) -> Optional[Sequence[types.CallHierarchyItem]]: - """Make a :lsp:`textDocument/prepareCallHierarchy` request. - - A request to result a `CallHierarchyItem` in a document at a given position. - Can be used as an input to an incoming or outgoing call hierarchy. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/prepareCallHierarchy", params) - - def text_document_prepare_rename( - self, - params: types.PrepareRenameParams, - callback: Optional[Callable[[Union[types.Range, types.PrepareRenamePlaceholder, types.PrepareRenameDefaultBehavior, None]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/prepareRename` request. - - A request to test and perform the setup necessary for a rename. - - @since 3.16 - support for default behavior - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/prepareRename", params, callback) - - async def text_document_prepare_rename_async( - self, - params: types.PrepareRenameParams, - ) -> Union[types.Range, types.PrepareRenamePlaceholder, types.PrepareRenameDefaultBehavior, None]: - """Make a :lsp:`textDocument/prepareRename` request. - - A request to test and perform the setup necessary for a rename. - - @since 3.16 - support for default behavior - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/prepareRename", params) - - def text_document_prepare_type_hierarchy( - self, - params: types.TypeHierarchyPrepareParams, - callback: Optional[Callable[[Optional[Sequence[types.TypeHierarchyItem]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/prepareTypeHierarchy` request. - - A request to result a `TypeHierarchyItem` in a document at a given position. - Can be used as an input to a subtypes or supertypes type hierarchy. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/prepareTypeHierarchy", params, callback) - - async def text_document_prepare_type_hierarchy_async( - self, - params: types.TypeHierarchyPrepareParams, - ) -> Optional[Sequence[types.TypeHierarchyItem]]: - """Make a :lsp:`textDocument/prepareTypeHierarchy` request. - - A request to result a `TypeHierarchyItem` in a document at a given position. - Can be used as an input to a subtypes or supertypes type hierarchy. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/prepareTypeHierarchy", params) - - def text_document_ranges_formatting( - self, - params: types.DocumentRangesFormattingParams, - callback: Optional[Callable[[Optional[Sequence[types.TextEdit]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/rangesFormatting` request. - - A request to format ranges in a document. - - @since 3.18.0 - @proposed - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/rangesFormatting", params, callback) - - async def text_document_ranges_formatting_async( - self, - params: types.DocumentRangesFormattingParams, - ) -> Optional[Sequence[types.TextEdit]]: - """Make a :lsp:`textDocument/rangesFormatting` request. - - A request to format ranges in a document. - - @since 3.18.0 - @proposed - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/rangesFormatting", params) - - def text_document_range_formatting( - self, - params: types.DocumentRangeFormattingParams, - callback: Optional[Callable[[Optional[Sequence[types.TextEdit]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/rangeFormatting` request. - - A request to format a range in a document. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/rangeFormatting", params, callback) - - async def text_document_range_formatting_async( - self, - params: types.DocumentRangeFormattingParams, - ) -> Optional[Sequence[types.TextEdit]]: - """Make a :lsp:`textDocument/rangeFormatting` request. - - A request to format a range in a document. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/rangeFormatting", params) - - def text_document_references( - self, - params: types.ReferenceParams, - callback: Optional[Callable[[Optional[Sequence[types.Location]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/references` request. - - A request to resolve project-wide references for the symbol denoted - by the given text document position. The request's parameter is of - type {@link ReferenceParams} the response is of type - {@link Location Location[]} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/references", params, callback) - - async def text_document_references_async( - self, - params: types.ReferenceParams, - ) -> Optional[Sequence[types.Location]]: - """Make a :lsp:`textDocument/references` request. - - A request to resolve project-wide references for the symbol denoted - by the given text document position. The request's parameter is of - type {@link ReferenceParams} the response is of type - {@link Location Location[]} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/references", params) - - def text_document_rename( - self, - params: types.RenameParams, - callback: Optional[Callable[[Optional[types.WorkspaceEdit]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/rename` request. - - A request to rename a symbol. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/rename", params, callback) - - async def text_document_rename_async( - self, - params: types.RenameParams, - ) -> Optional[types.WorkspaceEdit]: - """Make a :lsp:`textDocument/rename` request. - - A request to rename a symbol. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/rename", params) - - def text_document_selection_range( - self, - params: types.SelectionRangeParams, - callback: Optional[Callable[[Optional[Sequence[types.SelectionRange]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/selectionRange` request. - - A request to provide selection ranges in a document. The request's - parameter is of type {@link SelectionRangeParams}, the - response is of type {@link SelectionRange SelectionRange[]} or a Thenable - that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/selectionRange", params, callback) - - async def text_document_selection_range_async( - self, - params: types.SelectionRangeParams, - ) -> Optional[Sequence[types.SelectionRange]]: - """Make a :lsp:`textDocument/selectionRange` request. - - A request to provide selection ranges in a document. The request's - parameter is of type {@link SelectionRangeParams}, the - response is of type {@link SelectionRange SelectionRange[]} or a Thenable - that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/selectionRange", params) - - def text_document_semantic_tokens_full( - self, - params: types.SemanticTokensParams, - callback: Optional[Callable[[Optional[types.SemanticTokens]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/semanticTokens/full` request. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/semanticTokens/full", params, callback) - - async def text_document_semantic_tokens_full_async( - self, - params: types.SemanticTokensParams, - ) -> Optional[types.SemanticTokens]: - """Make a :lsp:`textDocument/semanticTokens/full` request. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/semanticTokens/full", params) - - def text_document_semantic_tokens_full_delta( - self, - params: types.SemanticTokensDeltaParams, - callback: Optional[Callable[[Union[types.SemanticTokens, types.SemanticTokensDelta, None]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/semanticTokens/full/delta` request. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/semanticTokens/full/delta", params, callback) - - async def text_document_semantic_tokens_full_delta_async( - self, - params: types.SemanticTokensDeltaParams, - ) -> Union[types.SemanticTokens, types.SemanticTokensDelta, None]: - """Make a :lsp:`textDocument/semanticTokens/full/delta` request. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/semanticTokens/full/delta", params) - - def text_document_semantic_tokens_range( - self, - params: types.SemanticTokensRangeParams, - callback: Optional[Callable[[Optional[types.SemanticTokens]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/semanticTokens/range` request. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/semanticTokens/range", params, callback) - - async def text_document_semantic_tokens_range_async( - self, - params: types.SemanticTokensRangeParams, - ) -> Optional[types.SemanticTokens]: - """Make a :lsp:`textDocument/semanticTokens/range` request. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/semanticTokens/range", params) - - def text_document_signature_help( - self, - params: types.SignatureHelpParams, - callback: Optional[Callable[[Optional[types.SignatureHelp]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/signatureHelp` request. - - - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/signatureHelp", params, callback) - - async def text_document_signature_help_async( - self, - params: types.SignatureHelpParams, - ) -> Optional[types.SignatureHelp]: - """Make a :lsp:`textDocument/signatureHelp` request. - - - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/signatureHelp", params) - - def text_document_type_definition( - self, - params: types.TypeDefinitionParams, - callback: Optional[Callable[[Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/typeDefinition` request. - - A request to resolve the type definition locations of a symbol at a given text - document position. The request's parameter is of type {@link TextDocumentPositionParams} - the response is of type {@link Definition} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/typeDefinition", params, callback) - - async def text_document_type_definition_async( - self, - params: types.TypeDefinitionParams, - ) -> Union[types.Location, Sequence[types.Location], Sequence[types.LocationLink], None]: - """Make a :lsp:`textDocument/typeDefinition` request. - - A request to resolve the type definition locations of a symbol at a given text - document position. The request's parameter is of type {@link TextDocumentPositionParams} - the response is of type {@link Definition} or a Thenable that resolves to such. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/typeDefinition", params) - - def text_document_will_save_wait_until( - self, - params: types.WillSaveTextDocumentParams, - callback: Optional[Callable[[Optional[Sequence[types.TextEdit]]], None]] = None, - ) -> Future: - """Make a :lsp:`textDocument/willSaveWaitUntil` request. - - A document will save request is sent from the client to the server before - the document is actually saved. The request can return an array of TextEdits - which will be applied to the text document before it is saved. Please note that - clients might drop results if computing the text edits took too long or if a - server constantly fails on this request. This is done to keep the save fast and - reliable. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("textDocument/willSaveWaitUntil", params, callback) - - async def text_document_will_save_wait_until_async( - self, - params: types.WillSaveTextDocumentParams, - ) -> Optional[Sequence[types.TextEdit]]: - """Make a :lsp:`textDocument/willSaveWaitUntil` request. - - A document will save request is sent from the client to the server before - the document is actually saved. The request can return an array of TextEdits - which will be applied to the text document before it is saved. Please note that - clients might drop results if computing the text edits took too long or if a - server constantly fails on this request. This is done to keep the save fast and - reliable. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("textDocument/willSaveWaitUntil", params) - - def type_hierarchy_subtypes( - self, - params: types.TypeHierarchySubtypesParams, - callback: Optional[Callable[[Optional[Sequence[types.TypeHierarchyItem]]], None]] = None, - ) -> Future: - """Make a :lsp:`typeHierarchy/subtypes` request. - - A request to resolve the subtypes for a given `TypeHierarchyItem`. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("typeHierarchy/subtypes", params, callback) - - async def type_hierarchy_subtypes_async( - self, - params: types.TypeHierarchySubtypesParams, - ) -> Optional[Sequence[types.TypeHierarchyItem]]: - """Make a :lsp:`typeHierarchy/subtypes` request. - - A request to resolve the subtypes for a given `TypeHierarchyItem`. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("typeHierarchy/subtypes", params) - - def type_hierarchy_supertypes( - self, - params: types.TypeHierarchySupertypesParams, - callback: Optional[Callable[[Optional[Sequence[types.TypeHierarchyItem]]], None]] = None, - ) -> Future: - """Make a :lsp:`typeHierarchy/supertypes` request. - - A request to resolve the supertypes for a given `TypeHierarchyItem`. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("typeHierarchy/supertypes", params, callback) - - async def type_hierarchy_supertypes_async( - self, - params: types.TypeHierarchySupertypesParams, - ) -> Optional[Sequence[types.TypeHierarchyItem]]: - """Make a :lsp:`typeHierarchy/supertypes` request. - - A request to resolve the supertypes for a given `TypeHierarchyItem`. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("typeHierarchy/supertypes", params) - - def workspace_diagnostic( - self, - params: types.WorkspaceDiagnosticParams, - callback: Optional[Callable[[types.WorkspaceDiagnosticReport], None]] = None, - ) -> Future: - """Make a :lsp:`workspace/diagnostic` request. - - The workspace diagnostic request definition. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("workspace/diagnostic", params, callback) - - async def workspace_diagnostic_async( - self, - params: types.WorkspaceDiagnosticParams, - ) -> types.WorkspaceDiagnosticReport: - """Make a :lsp:`workspace/diagnostic` request. - - The workspace diagnostic request definition. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("workspace/diagnostic", params) - - def workspace_execute_command( - self, - params: types.ExecuteCommandParams, - callback: Optional[Callable[[Optional[Any]], None]] = None, - ) -> Future: - """Make a :lsp:`workspace/executeCommand` request. - - A request send from the client to the server to execute a command. The request might return - a workspace edit which the client will apply to the workspace. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("workspace/executeCommand", params, callback) - - async def workspace_execute_command_async( - self, - params: types.ExecuteCommandParams, - ) -> Optional[Any]: - """Make a :lsp:`workspace/executeCommand` request. - - A request send from the client to the server to execute a command. The request might return - a workspace edit which the client will apply to the workspace. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("workspace/executeCommand", params) - - def workspace_symbol( - self, - params: types.WorkspaceSymbolParams, - callback: Optional[Callable[[Union[Sequence[types.SymbolInformation], Sequence[types.WorkspaceSymbol], None]], None]] = None, - ) -> Future: - """Make a :lsp:`workspace/symbol` request. - - A request to list project-wide symbols matching the query string given - by the {@link WorkspaceSymbolParams}. The response is - of type {@link SymbolInformation SymbolInformation[]} or a Thenable that - resolves to such. - - @since 3.17.0 - support for WorkspaceSymbol in the returned data. Clients - need to advertise support for WorkspaceSymbols via the client capability - `workspace.symbol.resolveSupport`. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("workspace/symbol", params, callback) - - async def workspace_symbol_async( - self, - params: types.WorkspaceSymbolParams, - ) -> Union[Sequence[types.SymbolInformation], Sequence[types.WorkspaceSymbol], None]: - """Make a :lsp:`workspace/symbol` request. - - A request to list project-wide symbols matching the query string given - by the {@link WorkspaceSymbolParams}. The response is - of type {@link SymbolInformation SymbolInformation[]} or a Thenable that - resolves to such. - - @since 3.17.0 - support for WorkspaceSymbol in the returned data. Clients - need to advertise support for WorkspaceSymbols via the client capability - `workspace.symbol.resolveSupport`. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("workspace/symbol", params) - - def workspace_symbol_resolve( - self, - params: types.WorkspaceSymbol, - callback: Optional[Callable[[types.WorkspaceSymbol], None]] = None, - ) -> Future: - """Make a :lsp:`workspaceSymbol/resolve` request. - - A request to resolve the range inside the workspace - symbol's location. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("workspaceSymbol/resolve", params, callback) - - async def workspace_symbol_resolve_async( - self, - params: types.WorkspaceSymbol, - ) -> types.WorkspaceSymbol: - """Make a :lsp:`workspaceSymbol/resolve` request. - - A request to resolve the range inside the workspace - symbol's location. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("workspaceSymbol/resolve", params) - - def workspace_text_document_content( - self, - params: types.TextDocumentContentParams, - callback: Optional[Callable[[str], None]] = None, - ) -> Future: - """Make a :lsp:`workspace/textDocumentContent` request. - - The `workspace/textDocumentContent` request is sent from the client to the - server to request the content of a text document. - - @since 3.18.0 - @proposed - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("workspace/textDocumentContent", params, callback) - - async def workspace_text_document_content_async( - self, - params: types.TextDocumentContentParams, - ) -> str: - """Make a :lsp:`workspace/textDocumentContent` request. - - The `workspace/textDocumentContent` request is sent from the client to the - server to request the content of a text document. - - @since 3.18.0 - @proposed - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("workspace/textDocumentContent", params) - - def workspace_will_create_files( - self, - params: types.CreateFilesParams, - callback: Optional[Callable[[Optional[types.WorkspaceEdit]], None]] = None, - ) -> Future: - """Make a :lsp:`workspace/willCreateFiles` request. - - The will create files request is sent from the client to the server before files are actually - created as long as the creation is triggered from within the client. - - The request can return a `WorkspaceEdit` which will be applied to workspace before the - files are created. Hence the `WorkspaceEdit` can not manipulate the content of the file - to be created. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("workspace/willCreateFiles", params, callback) - - async def workspace_will_create_files_async( - self, - params: types.CreateFilesParams, - ) -> Optional[types.WorkspaceEdit]: - """Make a :lsp:`workspace/willCreateFiles` request. - - The will create files request is sent from the client to the server before files are actually - created as long as the creation is triggered from within the client. - - The request can return a `WorkspaceEdit` which will be applied to workspace before the - files are created. Hence the `WorkspaceEdit` can not manipulate the content of the file - to be created. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("workspace/willCreateFiles", params) - - def workspace_will_delete_files( - self, - params: types.DeleteFilesParams, - callback: Optional[Callable[[Optional[types.WorkspaceEdit]], None]] = None, - ) -> Future: - """Make a :lsp:`workspace/willDeleteFiles` request. - - The did delete files notification is sent from the client to the server when - files were deleted from within the client. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("workspace/willDeleteFiles", params, callback) - - async def workspace_will_delete_files_async( - self, - params: types.DeleteFilesParams, - ) -> Optional[types.WorkspaceEdit]: - """Make a :lsp:`workspace/willDeleteFiles` request. - - The did delete files notification is sent from the client to the server when - files were deleted from within the client. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("workspace/willDeleteFiles", params) - - def workspace_will_rename_files( - self, - params: types.RenameFilesParams, - callback: Optional[Callable[[Optional[types.WorkspaceEdit]], None]] = None, - ) -> Future: - """Make a :lsp:`workspace/willRenameFiles` request. - - The will rename files request is sent from the client to the server before files are actually - renamed as long as the rename is triggered from within the client. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return self.protocol.send_request("workspace/willRenameFiles", params, callback) - - async def workspace_will_rename_files_async( - self, - params: types.RenameFilesParams, - ) -> Optional[types.WorkspaceEdit]: - """Make a :lsp:`workspace/willRenameFiles` request. - - The will rename files request is sent from the client to the server before files are actually - renamed as long as the rename is triggered from within the client. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - return await self.protocol.send_request_async("workspace/willRenameFiles", params) - - def cancel_request(self, params: types.CancelParams) -> None: - """Send a :lsp:`$/cancelRequest` notification. - - - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("$/cancelRequest", params) - - def exit(self, params: None) -> None: - """Send a :lsp:`exit` notification. - - The exit event is sent from the client to the server to - ask the server to exit its process. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("exit", params) - - def initialized(self, params: types.InitializedParams) -> None: - """Send a :lsp:`initialized` notification. - - The initialized notification is sent from the client to the - server after the client is fully initialized and the server - is allowed to send requests from the server to the client. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("initialized", params) - - def notebook_document_did_change(self, params: types.DidChangeNotebookDocumentParams) -> None: - """Send a :lsp:`notebookDocument/didChange` notification. - - - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("notebookDocument/didChange", params) - - def notebook_document_did_close(self, params: types.DidCloseNotebookDocumentParams) -> None: - """Send a :lsp:`notebookDocument/didClose` notification. - - A notification sent when a notebook closes. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("notebookDocument/didClose", params) - - def notebook_document_did_open(self, params: types.DidOpenNotebookDocumentParams) -> None: - """Send a :lsp:`notebookDocument/didOpen` notification. - - A notification sent when a notebook opens. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("notebookDocument/didOpen", params) - - def notebook_document_did_save(self, params: types.DidSaveNotebookDocumentParams) -> None: - """Send a :lsp:`notebookDocument/didSave` notification. - - A notification sent when a notebook document is saved. - - @since 3.17.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("notebookDocument/didSave", params) - - def progress(self, params: types.ProgressParams) -> None: - """Send a :lsp:`$/progress` notification. - - - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("$/progress", params) - - def set_trace(self, params: types.SetTraceParams) -> None: - """Send a :lsp:`$/setTrace` notification. - - - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("$/setTrace", params) - - def text_document_did_change(self, params: types.DidChangeTextDocumentParams) -> None: - """Send a :lsp:`textDocument/didChange` notification. - - The document change notification is sent from the client to the server to signal - changes to a text document. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("textDocument/didChange", params) - - def text_document_did_close(self, params: types.DidCloseTextDocumentParams) -> None: - """Send a :lsp:`textDocument/didClose` notification. - - The document close notification is sent from the client to the server when - the document got closed in the client. The document's truth now exists where - the document's uri points to (e.g. if the document's uri is a file uri the - truth now exists on disk). As with the open notification the close notification - is about managing the document's content. Receiving a close notification - doesn't mean that the document was open in an editor before. A close - notification requires a previous open notification to be sent. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("textDocument/didClose", params) - - def text_document_did_open(self, params: types.DidOpenTextDocumentParams) -> None: - """Send a :lsp:`textDocument/didOpen` notification. - - The document open notification is sent from the client to the server to signal - newly opened text documents. The document's truth is now managed by the client - and the server must not try to read the document's truth using the document's - uri. Open in this sense means it is managed by the client. It doesn't necessarily - mean that its content is presented in an editor. An open notification must not - be sent more than once without a corresponding close notification send before. - This means open and close notification must be balanced and the max open count - is one. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("textDocument/didOpen", params) - - def text_document_did_save(self, params: types.DidSaveTextDocumentParams) -> None: - """Send a :lsp:`textDocument/didSave` notification. - - The document save notification is sent from the client to the server when - the document got saved in the client. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("textDocument/didSave", params) - - def text_document_will_save(self, params: types.WillSaveTextDocumentParams) -> None: - """Send a :lsp:`textDocument/willSave` notification. - - A document will save notification is sent from the client to the server before - the document is actually saved. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("textDocument/willSave", params) - - def window_work_done_progress_cancel(self, params: types.WorkDoneProgressCancelParams) -> None: - """Send a :lsp:`window/workDoneProgress/cancel` notification. - - The `window/workDoneProgress/cancel` notification is sent from the client to the server to cancel a progress - initiated on the server side. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("window/workDoneProgress/cancel", params) - - def workspace_did_change_configuration(self, params: types.DidChangeConfigurationParams) -> None: - """Send a :lsp:`workspace/didChangeConfiguration` notification. - - The configuration change notification is sent from the client to the server - when the client's configuration has changed. The notification contains - the changed configuration as defined by the language client. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("workspace/didChangeConfiguration", params) - - def workspace_did_change_watched_files(self, params: types.DidChangeWatchedFilesParams) -> None: - """Send a :lsp:`workspace/didChangeWatchedFiles` notification. - - The watched files notification is sent from the client to the server when - the client detects changes to file watched by the language client. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("workspace/didChangeWatchedFiles", params) - - def workspace_did_change_workspace_folders(self, params: types.DidChangeWorkspaceFoldersParams) -> None: - """Send a :lsp:`workspace/didChangeWorkspaceFolders` notification. - - The `workspace/didChangeWorkspaceFolders` notification is sent from the client to the server when the workspace - folder configuration changes. - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("workspace/didChangeWorkspaceFolders", params) - - def workspace_did_create_files(self, params: types.CreateFilesParams) -> None: - """Send a :lsp:`workspace/didCreateFiles` notification. - - The did create files notification is sent from the client to the server when - files were created from within the client. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("workspace/didCreateFiles", params) - - def workspace_did_delete_files(self, params: types.DeleteFilesParams) -> None: - """Send a :lsp:`workspace/didDeleteFiles` notification. - - The will delete files request is sent from the client to the server before files are actually - deleted as long as the deletion is triggered from within the client. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("workspace/didDeleteFiles", params) - - def workspace_did_rename_files(self, params: types.RenameFilesParams) -> None: - """Send a :lsp:`workspace/didRenameFiles` notification. - - The did rename files notification is sent from the client to the server when - files were renamed from within the client. - - @since 3.16.0 - """ - if self.stopped: - raise RuntimeError("Client has been stopped.") - - self.protocol.notify("workspace/didRenameFiles", params) +# Placeholder for when we add a real client +class LanguageClient(BaseLanguageClient): + """Language client.""" diff --git a/pyproject.toml b/pyproject.toml index 9f0acbe1..02be3f56 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,7 +58,7 @@ ruff = "ruff check ." mypy = "mypy -p pygls" check_generated_client = "python scripts/check_client_is_uptodate.py" check_commit_style = "npx commitlint --from origin/main --to HEAD --verbose --config commitlintrc.yaml" -generate_client = "python scripts/generate_client.py --output pygls/lsp/client.py" +generate_client = "python scripts/generate_client_server.py pygls/lsp" generate_contributors_md = "python scripts/generate_contributors_md.py" black_check = "black --check ." poetry_lock_check = "poetry check" @@ -95,7 +95,7 @@ line-length = 120 [tool.black] line-length = 88 -extend-exclude = "pygls/lsp/client.py" +extend-exclude = "pygls/lsp/_base_.*.py" [tool.coverage.run] parallel = true diff --git a/scripts/check_client_is_uptodate.py b/scripts/check_client_is_uptodate.py index 1c5b1be2..0db2a033 100644 --- a/scripts/check_client_is_uptodate.py +++ b/scripts/check_client_is_uptodate.py @@ -1,20 +1,30 @@ import sys import subprocess -AUTOGENERATED_CLIENT_FILE = "pygls/lsp/client.py" +AUTOGENERATED_CLIENT_FILE = "pygls/lsp/_base_client.py" +AUTOGENERATED_SERVER_FILE = "pygls/lsp/_base_server.py" subprocess.run(["poe", "generate_client"]) result = subprocess.run( - ["git", "diff", "--exit-code", AUTOGENERATED_CLIENT_FILE], stdout=subprocess.DEVNULL + [ + "git", + "diff", + "--exit-code", + AUTOGENERATED_CLIENT_FILE, + AUTOGENERATED_SERVER_FILE, + ], + stdout=subprocess.DEVNULL, ) if result.returncode == 0: - print("✅ Pygls client is up to date") + print("✅ Pygls client and server are up to date") else: print( - "🔴 Pygls client not uptodate\n" - "1. Generate with: `poetry run poe generate_client`\n" - "2. Commit" + ( + "🔴 Pygls client or server not up to date\n" + "1. Re-generate with: `poetry run poe generate_client`\n" + "2. Commit" + ) ) sys.exit(result.returncode) diff --git a/scripts/generate_client.py b/scripts/generate_client_server.py similarity index 55% rename from scripts/generate_client.py rename to scripts/generate_client_server.py index 72d0ea82..82675a55 100644 --- a/scripts/generate_client.py +++ b/scripts/generate_client_server.py @@ -1,11 +1,9 @@ -"""Script to automatically generate a lanaguge client from `lsprotocol` type definitons -""" +"""Script to automatically generate a lanaguge client from `lsprotocol` type definitons""" import argparse import inspect import pathlib import re -import sys import textwrap from typing import Optional from typing import Set @@ -19,7 +17,7 @@ cli = argparse.ArgumentParser( description="generate language client from lsprotocol types." ) -cli.add_argument("-o", "--output", default=None) +cli.add_argument("output", type=pathlib.Path) def write_imports(imports: Set[Tuple[str, str]]) -> str: @@ -40,7 +38,7 @@ def to_snake_case(string: str) -> str: return "".join(f"_{c.lower()}" if c.isupper() else c for c in string) -def write_notification( +def write_client_notification( method: str, request: Type, params: Optional[Type], @@ -71,6 +69,37 @@ def write_notification( ) +def write_server_notification( + method: str, + request: Type, + params: Optional[Type], + imports: Set[Tuple[str, str]], +) -> str: + python_name = to_snake_case(method).replace("/", "_").replace("$_", "") + + if params is None: + param_name = "None" + param_mod = "" + elif "lsprotocol" not in str(params): + param_mod = str(params) + param_name = "" + else: + param_mod, param_name = params.__module__, params.__name__ + param_mod = param_mod.replace("lsprotocol.types", "types") + "." + + return "\n".join( + [ + f"def {python_name}(self, params: {param_mod}{param_name}) -> None:", + f' """Send a :lsp:`{method}` notification.', + "", + textwrap.indent(inspect.getdoc(request) or "", " "), + ' """', + f' self.protocol.notify("{method}", params)', + "", + ] + ) + + def get_response_type(response: Type, imports: Set[Tuple[str, str]]) -> str: # Find the response type. result_field = [f for f in response.__attrs_attrs__ if f.name == "result"][0] @@ -88,7 +117,7 @@ def get_response_type(response: Type, imports: Set[Tuple[str, str]]) -> str: return result -def write_method( +def write_client_method( method: str, request: Type, params: Optional[Type], @@ -139,6 +168,51 @@ def write_method( ) +def write_server_method( + method: str, + request: Type, + params: Optional[Type], + response: Type, + imports: Set[Tuple[str, str]], +) -> str: + python_name = to_snake_case(method).replace("/", "_").replace("$_", "") + + if params is None: + param_name = "None" + param_mod = "" + else: + param_mod, param_name = params.__module__, params.__name__ + param_mod = param_mod.replace("lsprotocol.types", "types") + "." + + result_type = get_response_type(response, imports) + + return "\n".join( + [ + f"def {python_name}(", + " self,", + f" params: {param_mod}{param_name},", + f" callback: Optional[Callable[[{result_type}], None]] = None,", + ") -> Future:", + f' """Make a :lsp:`{method}` request.', + "", + textwrap.indent(inspect.getdoc(request) or "", " "), + ' """', + f' return self.protocol.send_request("{method}", params, callback)', + "", + f"async def {python_name}_async(", + " self,", + f" params: {param_mod}{param_name},", + f") -> {result_type}:", + f' """Make a :lsp:`{method}` request.', + "", + textwrap.indent(inspect.getdoc(request) or "", " "), + ' """', + f' return await self.protocol.send_request_async("{method}", params)', + "", + ] + ) + + def generate_client() -> str: methods = [] imports = { @@ -159,14 +233,16 @@ def generate_client() -> str: request, response, params, _ = types if response is None: - method = write_notification(method_name, request, params, imports) + method = write_client_notification(method_name, request, params, imports) else: - method = write_method(method_name, request, params, response, imports) + method = write_client_method( + method_name, request, params, response, imports + ) methods.append(textwrap.indent(method, " ")) code = [ - "# GENERATED FROM scripts/gen-client.py -- DO NOT EDIT", + "# GENERATED FROM scripts/generate_client_server.py -- DO NOT EDIT", "# flake8: noqa", write_imports(imports), "", @@ -190,18 +266,74 @@ def generate_client() -> str: return "\n".join(code) +def generate_server() -> str: + methods = [] + imports = { + "typing", + ("concurrent.futures", "Future"), + ("lsprotocol", "types"), + ("cattrs", "Converter"), + ("pygls.protocol", "LanguageServerProtocol"), + ("pygls.protocol", "default_converter"), + ("pygls.server", "Server"), + ("typing", "Callable"), + ("typing", "Optional"), + ("typing", "Type"), + } + + for method_name, types in METHOD_TO_TYPES.items(): + # Skip any requests that come from the client. + if message_direction(method_name) == "clientToServer": + continue + + request, response, params, _ = types + + if response is None: + method = write_server_notification(method_name, request, params, imports) + else: + method = write_server_method( + method_name, request, params, response, imports + ) + + methods.append(textwrap.indent(method, " ")) + + code = [ + "# GENERATED FROM scripts/generate_client_server.py -- DO NOT EDIT", + "# flake8: noqa", + write_imports(imports), + "", + "", + "class BaseLanguageServer(Server):", + "", + " protocol: LanguageServerProtocol", + "", + " def __init__(", + " self,", + " protocol_cls: Type[LanguageServerProtocol] = LanguageServerProtocol,", + " converter_factory: Callable[[], Converter] = default_converter,", + " loop=None,", + " **kwargs,", + " ):", + " super().__init__(protocol_cls, converter_factory, loop, **kwargs)", + "", + *methods, + ] + return "\n".join(code) + + def main(): args = cli.parse_args() # Make sure all the type annotations in lsprotocol are resolved correctly. _resolve_forward_references() + client = generate_client() + output = args.output / "_base_client.py" + output.write_text(client) - if args.output is None: - sys.stdout.write(client) - else: - output = pathlib.Path(args.output) - output.write_text(client) + server = generate_server() + output = args.output / "_base_server.py" + output.write_text(server) if __name__ == "__main__": From 652a34a08dd2527ea2917c4d8f4718428855c63a Mon Sep 17 00:00:00 2001 From: Alex Carney Date: Wed, 14 Aug 2024 19:54:25 +0100 Subject: [PATCH 2/9] chore: remove redundant method definitions --- pygls/protocol/language_server.py | 387 ++++-------------------------- 1 file changed, 44 insertions(+), 343 deletions(-) diff --git a/pygls/protocol/language_server.py b/pygls/protocol/language_server.py index 9132eabc..6c5e2b76 100644 --- a/pygls/protocol/language_server.py +++ b/pygls/protocol/language_server.py @@ -15,86 +15,32 @@ # limitations under the License. # ############################################################################ from __future__ import annotations -import asyncio + import json import logging import sys -from concurrent.futures import Future +import typing from functools import lru_cache from itertools import zip_longest from typing import ( Callable, - List, Optional, Type, TypeVar, - Union, ) +from lsprotocol import types from pygls.capabilities import ServerCapabilitiesBuilder -from pygls.lsp import ConfigCallbackType, ShowDocumentCallbackType -from lsprotocol.types import ( - CLIENT_REGISTER_CAPABILITY, - CLIENT_UNREGISTER_CAPABILITY, - EXIT, - INITIALIZE, - INITIALIZED, - METHOD_TO_TYPES, - NOTEBOOK_DOCUMENT_DID_CHANGE, - NOTEBOOK_DOCUMENT_DID_CLOSE, - NOTEBOOK_DOCUMENT_DID_OPEN, - LOG_TRACE, - SET_TRACE, - SHUTDOWN, - TEXT_DOCUMENT_DID_CHANGE, - TEXT_DOCUMENT_DID_CLOSE, - TEXT_DOCUMENT_DID_OPEN, - TEXT_DOCUMENT_PUBLISH_DIAGNOSTICS, - WINDOW_LOG_MESSAGE, - WINDOW_SHOW_DOCUMENT, - WINDOW_SHOW_MESSAGE, - WINDOW_WORK_DONE_PROGRESS_CANCEL, - WORKSPACE_APPLY_EDIT, - WORKSPACE_CONFIGURATION, - WORKSPACE_DID_CHANGE_WORKSPACE_FOLDERS, - WORKSPACE_EXECUTE_COMMAND, - WORKSPACE_SEMANTIC_TOKENS_REFRESH, -) -from lsprotocol.types import ( - ApplyWorkspaceEditParams, - Diagnostic, - DidChangeNotebookDocumentParams, - DidChangeTextDocumentParams, - DidChangeWorkspaceFoldersParams, - DidCloseNotebookDocumentParams, - DidCloseTextDocumentParams, - DidOpenNotebookDocumentParams, - DidOpenTextDocumentParams, - ExecuteCommandParams, - InitializeParams, - InitializeResult, - LogMessageParams, - LogTraceParams, - MessageType, - PublishDiagnosticsParams, - RegistrationParams, - SetTraceParams, - ShowDocumentParams, - ShowMessageParams, - TraceValue, - UnregistrationParams, - ApplyWorkspaceEditResponse, - WorkspaceEdit, - ServerInfo, - ConfigurationParams, - WorkDoneProgressCancelParams, -) from pygls.protocol.json_rpc import JsonRPCProtocol from pygls.protocol.lsp_meta import LSPMeta from pygls.uris import from_fs_path from pygls.workspace import Workspace +if typing.TYPE_CHECKING: + from cattrs import Converter + + from pygls.lsp.server import LanguageServer F = TypeVar("F", bound=Callable) @@ -118,17 +64,19 @@ class LanguageServerProtocol(JsonRPCProtocol, metaclass=LSPMeta): workspace(Workspace): In memory workspace """ - def __init__(self, server, converter): + _server: LanguageServer + + def __init__(self, server: LanguageServer, converter: Converter): super().__init__(server, converter) self._workspace: Optional[Workspace] = None - self.trace = None + self.trace = types.TraceValue.Off from pygls.progress import Progress self.progress = Progress(self) - self.server_info = ServerInfo( + self.server_info = types.ServerInfo( name=server.name, version=server.version, ) @@ -157,29 +105,13 @@ def workspace(self) -> Workspace: @lru_cache() def get_message_type(self, method: str) -> Optional[Type]: """Return LSP type definitions, as provided by `lsprotocol`""" - return METHOD_TO_TYPES.get(method, (None,))[0] + return types.METHOD_TO_TYPES.get(method, (None,))[0] @lru_cache() def get_result_type(self, method: str) -> Optional[Type]: - return METHOD_TO_TYPES.get(method, (None, None))[1] - - def apply_edit( - self, edit: WorkspaceEdit, label: Optional[str] = None - ) -> ApplyWorkspaceEditResponse: - """Sends apply edit request to the client.""" - return self.send_request( - WORKSPACE_APPLY_EDIT, ApplyWorkspaceEditParams(edit=edit, label=label) - ) + return types.METHOD_TO_TYPES.get(method, (None, None))[1] - def apply_edit_async( - self, edit: WorkspaceEdit, label: Optional[str] = None - ) -> ApplyWorkspaceEditResponse: - """Sends apply edit request to the client. Should be called with `await`""" - return self.send_request_async( - WORKSPACE_APPLY_EDIT, ApplyWorkspaceEditParams(edit=edit, label=label) - ) - - @lsp_method(EXIT) + @lsp_method(types.EXIT) def lsp_exit(self, *args) -> None: """Stops the server process.""" if self.transport is not None: @@ -187,8 +119,8 @@ def lsp_exit(self, *args) -> None: sys.exit(0 if self._shutdown else 1) - @lsp_method(INITIALIZE) - def lsp_initialize(self, params: InitializeParams) -> InitializeResult: + @lsp_method(types.INITIALIZE) + def lsp_initialize(self, params: types.InitializeParams) -> types.InitializeResult: """Method that initializes language server. It will compute and return server capabilities based on registered features. @@ -229,19 +161,17 @@ def lsp_initialize(self, params: InitializeParams) -> InitializeResult: self.server_capabilities.position_encoding, ) - self.trace = TraceValue.Off - - return InitializeResult( + return types.InitializeResult( capabilities=self.server_capabilities, server_info=self.server_info, ) - @lsp_method(INITIALIZED) + @lsp_method(types.INITIALIZED) def lsp_initialized(self, *args) -> None: """Notification received when client and server are connected.""" pass - @lsp_method(SHUTDOWN) + @lsp_method(types.SHUTDOWN) def lsp_shutdown(self, *args) -> None: """Request from client which asks server to shutdown.""" for future in self._request_futures.values(): @@ -250,9 +180,9 @@ def lsp_shutdown(self, *args) -> None: self._shutdown = True return None - @lsp_method(TEXT_DOCUMENT_DID_CHANGE) + @lsp_method(types.TEXT_DOCUMENT_DID_CHANGE) def lsp_text_document__did_change( - self, params: DidChangeTextDocumentParams + self, params: types.DidChangeTextDocumentParams ) -> None: """Updates document's content. (Incremental(from server capabilities); not configurable for now) @@ -260,45 +190,49 @@ def lsp_text_document__did_change( for change in params.content_changes: self.workspace.update_text_document(params.text_document, change) - @lsp_method(TEXT_DOCUMENT_DID_CLOSE) - def lsp_text_document__did_close(self, params: DidCloseTextDocumentParams) -> None: + @lsp_method(types.TEXT_DOCUMENT_DID_CLOSE) + def lsp_text_document__did_close( + self, params: types.DidCloseTextDocumentParams + ) -> None: """Removes document from workspace.""" self.workspace.remove_text_document(params.text_document.uri) - @lsp_method(TEXT_DOCUMENT_DID_OPEN) - def lsp_text_document__did_open(self, params: DidOpenTextDocumentParams) -> None: + @lsp_method(types.TEXT_DOCUMENT_DID_OPEN) + def lsp_text_document__did_open( + self, params: types.DidOpenTextDocumentParams + ) -> None: """Puts document to the workspace.""" self.workspace.put_text_document(params.text_document) - @lsp_method(NOTEBOOK_DOCUMENT_DID_OPEN) + @lsp_method(types.NOTEBOOK_DOCUMENT_DID_OPEN) def lsp_notebook_document__did_open( - self, params: DidOpenNotebookDocumentParams + self, params: types.DidOpenNotebookDocumentParams ) -> None: """Put a notebook document into the workspace""" self.workspace.put_notebook_document(params) - @lsp_method(NOTEBOOK_DOCUMENT_DID_CHANGE) + @lsp_method(types.NOTEBOOK_DOCUMENT_DID_CHANGE) def lsp_notebook_document__did_change( - self, params: DidChangeNotebookDocumentParams + self, params: types.DidChangeNotebookDocumentParams ) -> None: """Update a notebook's contents""" self.workspace.update_notebook_document(params) - @lsp_method(NOTEBOOK_DOCUMENT_DID_CLOSE) + @lsp_method(types.NOTEBOOK_DOCUMENT_DID_CLOSE) def lsp_notebook_document__did_close( - self, params: DidCloseNotebookDocumentParams + self, params: types.DidCloseNotebookDocumentParams ) -> None: """Remove a notebook document from the workspace.""" self.workspace.remove_notebook_document(params) - @lsp_method(SET_TRACE) - def lsp_set_trace(self, params: SetTraceParams) -> None: + @lsp_method(types.SET_TRACE) + def lsp_set_trace(self, params: types.SetTraceParams) -> None: """Changes server trace value.""" self.trace = params.value - @lsp_method(WORKSPACE_DID_CHANGE_WORKSPACE_FOLDERS) + @lsp_method(types.WORKSPACE_DID_CHANGE_WORKSPACE_FOLDERS) def lsp_workspace__did_change_workspace_folders( - self, params: DidChangeWorkspaceFoldersParams + self, params: types.DidChangeWorkspaceFoldersParams ) -> None: """Adds/Removes folders from the workspace.""" logger.info("Workspace folders changed: %s", params) @@ -312,17 +246,17 @@ def lsp_workspace__did_change_workspace_folders( if f_remove: self.workspace.remove_folder(f_remove.uri) - @lsp_method(WORKSPACE_EXECUTE_COMMAND) + @lsp_method(types.WORKSPACE_EXECUTE_COMMAND) def lsp_workspace__execute_command( - self, params: ExecuteCommandParams, msg_id: str + self, params: types.ExecuteCommandParams, msg_id: str ) -> None: """Executes commands with passed arguments and returns a value.""" cmd_handler = self.fm.commands[params.command] self._execute_request(msg_id, cmd_handler, params.arguments) - @lsp_method(WINDOW_WORK_DONE_PROGRESS_CANCEL) + @lsp_method(types.WINDOW_WORK_DONE_PROGRESS_CANCEL) def lsp_work_done_progress_cancel( - self, params: WorkDoneProgressCancelParams + self, params: types.WorkDoneProgressCancelParams ) -> None: """Received a progress cancellation from client.""" future = self.progress.tokens.get(params.token) @@ -332,236 +266,3 @@ def lsp_work_done_progress_cancel( ) else: future.cancel() - - def get_configuration( - self, - params: ConfigurationParams, - callback: Optional[ConfigCallbackType] = None, - ) -> Future: - """Sends configuration request to the client. - - Args: - params(ConfigurationParams): ConfigurationParams from lsp specs - callback(callable): Callable which will be called after - response from the client is received - Returns: - concurrent.futures.Future object that will be resolved once a - response has been received - """ - return self.send_request(WORKSPACE_CONFIGURATION, params, callback) - - def get_configuration_async(self, params: ConfigurationParams) -> asyncio.Future: - """Calls `get_configuration` method but designed to use with coroutines - - Args: - params(ConfigurationParams): ConfigurationParams from lsp specs - Returns: - asyncio.Future that can be awaited - """ - return asyncio.wrap_future(self.get_configuration(params)) - - def log_trace(self, message: str, verbose: Optional[str] = None) -> None: - """Sends trace notification to the client.""" - if self.trace == TraceValue.Off: - return - - params = LogTraceParams(message=message) - if verbose and self.trace == TraceValue.Verbose: - params.verbose = verbose - - self.notify(LOG_TRACE, params) - - def _publish_diagnostics_deprecator( - self, - params_or_uri: Union[str, PublishDiagnosticsParams], - diagnostics: Optional[List[Diagnostic]], - version: Optional[int], - **kwargs, - ) -> PublishDiagnosticsParams: - if isinstance(params_or_uri, str): - message = "DEPRECATION: " - "`publish_diagnostics(" - "self, doc_uri: str, diagnostics: List[Diagnostic], version: Optional[int] = None)`" - "will be replaced with `publish_diagnostics(self, params: PublishDiagnosticsParams)`" - logging.warning(message) - - params = self._construct_publish_diagnostic_type( - params_or_uri, diagnostics, version, **kwargs - ) - else: - params = params_or_uri - return params - - def _construct_publish_diagnostic_type( - self, - uri: str, - diagnostics: Optional[List[Diagnostic]], - version: Optional[int], - **kwargs, - ) -> PublishDiagnosticsParams: - if diagnostics is None: - diagnostics = [] - - args = { - **{"uri": uri, "diagnostics": diagnostics, "version": version}, - **kwargs, - } - - params = PublishDiagnosticsParams(**args) # type:ignore - return params - - def publish_diagnostics( - self, - params_or_uri: Union[str, PublishDiagnosticsParams], - diagnostics: Optional[List[Diagnostic]] = None, - version: Optional[int] = None, - **kwargs, - ): - """Sends diagnostic notification to the client. - - .. deprecated:: 1.0.1 - - Passing ``(uri, diagnostics, version)`` as arguments is deprecated. - Pass an instance of :class:`~lsprotocol.types.PublishDiagnosticParams` - instead. - - Parameters - ---------- - params_or_uri - The :class:`~lsprotocol.types.PublishDiagnosticParams` to send to the client. - - diagnostics - *Deprecated*. The diagnostics to publish - - version - *Deprecated*: The version number - """ - params = self._publish_diagnostics_deprecator( - params_or_uri, diagnostics, version, **kwargs - ) - self.notify(TEXT_DOCUMENT_PUBLISH_DIAGNOSTICS, params) - - def register_capability( - self, params: RegistrationParams, callback: Optional[Callable[[], None]] = None - ) -> Future: - """Register a new capability on the client. - - Args: - params(RegistrationParams): RegistrationParams from lsp specs - callback(callable): Callabe which will be called after - response from the client is received - Returns: - concurrent.futures.Future object that will be resolved once a - response has been received - """ - return self.send_request(CLIENT_REGISTER_CAPABILITY, params, callback) - - def register_capability_async(self, params: RegistrationParams) -> asyncio.Future: - """Register a new capability on the client. - - Args: - params(RegistrationParams): RegistrationParams from lsp specs - - Returns: - asyncio.Future object that will be resolved once a - response has been received - """ - return asyncio.wrap_future(self.register_capability(params, None)) - - def semantic_tokens_refresh( - self, callback: Optional[Callable[[], None]] = None - ) -> Future: - """Requesting a refresh of all semantic tokens. - - Args: - callback(callable): Callabe which will be called after - response from the client is received - - Returns: - concurrent.futures.Future object that will be resolved once a - response has been received - """ - return self.send_request(WORKSPACE_SEMANTIC_TOKENS_REFRESH, callback=callback) - - def semantic_tokens_refresh_async(self) -> asyncio.Future: - """Requesting a refresh of all semantic tokens. - - Returns: - asyncio.Future object that will be resolved once a - response has been received - """ - return asyncio.wrap_future(self.semantic_tokens_refresh(None)) - - def show_document( - self, - params: ShowDocumentParams, - callback: Optional[ShowDocumentCallbackType] = None, - ) -> Future: - """Display a particular document in the user interface. - - Args: - params(ShowDocumentParams): ShowDocumentParams from lsp specs - callback(callable): Callabe which will be called after - response from the client is received - - Returns: - concurrent.futures.Future object that will be resolved once a - response has been received - """ - return self.send_request(WINDOW_SHOW_DOCUMENT, params, callback) - - def show_document_async(self, params: ShowDocumentParams) -> asyncio.Future: - """Display a particular document in the user interface. - - Args: - params(ShowDocumentParams): ShowDocumentParams from lsp specs - - Returns: - asyncio.Future object that will be resolved once a - response has been received - """ - return asyncio.wrap_future(self.show_document(params, None)) - - def show_message(self, message, msg_type=MessageType.Info): - """Sends message to the client to display message.""" - self.notify( - WINDOW_SHOW_MESSAGE, ShowMessageParams(type=msg_type, message=message) - ) - - def show_message_log(self, message, msg_type=MessageType.Log): - """Sends message to the client's output channel.""" - self.notify( - WINDOW_LOG_MESSAGE, LogMessageParams(type=msg_type, message=message) - ) - - def unregister_capability( - self, - params: UnregistrationParams, - callback: Optional[Callable[[], None]] = None, - ) -> Future: - """Unregister a new capability on the client. - - Args: - params(UnregistrationParams): UnregistrationParams from lsp specs - callback(callable): Callabe which will be called after - response from the client is received - Returns: - concurrent.futures.Future object that will be resolved once a - response has been received - """ - return self.send_request(CLIENT_UNREGISTER_CAPABILITY, params, callback) - - def unregister_capability_async( - self, params: UnregistrationParams - ) -> asyncio.Future: - """Unregister a new capability on the client. - - Args: - params(UnregistrationParams): UnregistrationParams from lsp specs - callback(callable): Callabe which will be called after - response from the client is received - Returns: - asyncio.Future object that will be resolved once a - response has been received - """ - return asyncio.wrap_future(self.unregister_capability(params, None)) From a2fb2e8ce37df3307ec0a5ca5b75eaed5340e715 Mon Sep 17 00:00:00 2001 From: Alex Carney Date: Wed, 14 Aug 2024 20:09:08 +0100 Subject: [PATCH 3/9] refactor: use generated `BaseLanguageServer` This commit refactors the `LanguageServer` class to be based on the new `BaseLanguageServer`. The server has also been moved into the `pygls.lsp` module in an attempt to be more consistent with the client side code. It also takes the opportunity to tidy a few things up - Pushing generic server features such as error reporting and feature registration down into the base `Server` class - Removing LSP specific quirks from the base class e.g. `TextDocumentSyncKind` - Renames `server.lsp` to `server.protocol` to align better with the client code --- pygls/lsp/server.py | 126 +++++++++++++ pygls/protocol/json_rpc.py | 15 +- pygls/server.py | 350 ++++++------------------------------- 3 files changed, 185 insertions(+), 306 deletions(-) create mode 100644 pygls/lsp/server.py diff --git a/pygls/lsp/server.py b/pygls/lsp/server.py new file mode 100644 index 00000000..30692fb3 --- /dev/null +++ b/pygls/lsp/server.py @@ -0,0 +1,126 @@ +from __future__ import annotations + +import typing + +from lsprotocol import types + +from pygls.exceptions import FeatureRequestError + +from ._base_server import BaseLanguageServer + +if typing.TYPE_CHECKING: + from typing import Callable + from typing import TypeVar + + from pygls.server import ServerErrors + from pygls.progress import Progress + from pygls.workspace import Workspace + + F = TypeVar("F", bound=Callable) + + +class LanguageServer(BaseLanguageServer): + """The default LanguageServer + + This class can be extended and it can be passed as a first argument to + registered commands/features. + + .. |ServerInfo| replace:: :class:`~lsprotocol.types.ServerInfo` + + Parameters + ---------- + name + Name of the server, used to populate |ServerInfo| which is sent to + the client during initialization + + version + Version of the server, used to populate |ServerInfo| which is sent to + the client during initialization + + protocol_cls + The :class:`~pygls.protocol.LanguageServerProtocol` class definition, or any + subclass of it. + + max_workers + Maximum number of workers for ``ThreadPool`` and ``ThreadPoolExecutor`` + + text_document_sync_kind + Text document synchronization method + + None + No synchronization + + :attr:`~lsprotocol.types.TextDocumentSyncKind.Full` + Send entire document text with each update + + :attr:`~lsprotocol.types.TextDocumentSyncKind.Incremental` + Send only the region of text that changed with each update + + notebook_document_sync + Advertise :lsp:`NotebookDocument` support to the client. + """ + + def __init__( + self, + name: str, + version: str, + text_document_sync_kind: types.TextDocumentSyncKind = types.TextDocumentSyncKind.Incremental, + notebook_document_sync: types.NotebookDocumentSyncOptions | None = None, + *args, + **kwargs, + ): + self.name = name + self.version = version + self._text_document_sync_kind = text_document_sync_kind + self._notebook_document_sync = notebook_document_sync + self.process_id: int | None = None + super().__init__(*args, **kwargs) + + @property + def client_capabilities(self) -> types.ClientCapabilities: + """The client's capabilities.""" + return self.protocol.client_capabilities + + @property + def server_capabilities(self) -> types.ServerCapabilities: + """The server's capabilities.""" + return self.protocol.server_capabilities + + @property + def workspace(self) -> Workspace: + """Returns in-memory workspace.""" + return self.protocol.workspace + + @property + def work_done_progress(self) -> Progress: + """Gets the object to manage client's progress bar.""" + return self.protocol.progress + + def report_server_error(self, error: Exception, source: ServerErrors): + """ + Sends error to the client for displaying. + + By default this function does not handle LSP request errors. This is because LSP requests + require direct responses and so already have a mechanism for including unexpected errors + in the response body. + + All other errors are "out of band" in the sense that the client isn't explicitly waiting + for them. For example diagnostics are returned as notifications, not responses to requests, + and so can seemingly be sent at random. Also for example consider JSON RPC serialization + and deserialization, if a payload cannot be parsed then the whole request/response cycle + cannot be completed and so one of these "out of band" error messages is sent. + + These "out of band" error messages are not a requirement of the LSP spec. Pygls simply + offers this behaviour as a recommended default. It is perfectly reasonble to override this + default. + """ + + if source == FeatureRequestError: + return + + self.window_show_message( + types.ShowMessageParams( + message=f"Error in server: {error}", + type=types.MessageType.Error, + ) + ) diff --git a/pygls/protocol/json_rpc.py b/pygls/protocol/json_rpc.py index 75a4b34a..fd80595b 100644 --- a/pygls/protocol/json_rpc.py +++ b/pygls/protocol/json_rpc.py @@ -35,10 +35,6 @@ TYPE_CHECKING, ) -if TYPE_CHECKING: - from pygls.server import LanguageServer, WebSocketTransportAdapter - - import attrs from cattrs.errors import ClassValidationError @@ -61,6 +57,11 @@ ) from pygls.feature_manager import FeatureManager, is_thread_function +if TYPE_CHECKING: + from cattrs import Converter + from pygls.server import Server, WebSocketTransportAdapter + + logger = logging.getLogger(__name__) @@ -120,7 +121,7 @@ class JsonRPCProtocol(asyncio.Protocol): VERSION = "2.0" - def __init__(self, server: LanguageServer, converter): + def __init__(self, server: Server, converter: Converter): self._server = server self._converter = converter @@ -554,7 +555,3 @@ def send_request_async(self, method, params=None, msg_id=None): return asyncio.wrap_future( self.send_request(method, params=params, msg_id=msg_id) ) - - def thread(self): - """Decorator that mark function to execute it in a thread.""" - return self.fm.thread() diff --git a/pygls/server.py b/pygls/server.py index 3ddfbff4..29aee81f 100644 --- a/pygls/server.py +++ b/pygls/server.py @@ -14,27 +14,19 @@ # See the License for the specific language governing permissions and # # limitations under the License. # ############################################################################ +from __future__ import annotations + import asyncio import json import logging import re import sys -from concurrent.futures import Future, ThreadPoolExecutor +from concurrent.futures import ThreadPoolExecutor from threading import Event -from typing import ( - Any, - Callable, - List, - Optional, - TextIO, - Type, - TypeVar, - Union, -) +from typing import Any, Callable, Optional, TextIO, Type, TypeVar, Union import cattrs from pygls import IS_PYODIDE -from pygls.lsp import ConfigCallbackType, ShowDocumentCallbackType from pygls.exceptions import ( FeatureNotificationError, JsonRpcInternalError, @@ -42,23 +34,7 @@ JsonRpcException, FeatureRequestError, ) -from lsprotocol.types import ( - ClientCapabilities, - Diagnostic, - MessageType, - NotebookDocumentSyncOptions, - RegistrationParams, - ServerCapabilities, - ShowDocumentParams, - TextDocumentSyncKind, - UnregistrationParams, - ApplyWorkspaceEditResponse, - WorkspaceEdit, - ConfigurationParams, -) -from pygls.progress import Progress -from pygls.protocol import JsonRPCProtocol, LanguageServerProtocol, default_converter -from pygls.workspace import Workspace +from pygls.protocol import JsonRPCProtocol if not IS_PYODIDE: from multiprocessing.pool import ThreadPool @@ -190,13 +166,14 @@ class Server: """ + protocol: JsonRPCProtocol + def __init__( self, protocol_cls: Type[JsonRPCProtocol], converter_factory: Callable[[], cattrs.Converter], loop: Optional[asyncio.AbstractEventLoop] = None, max_workers: int = 2, - sync_kind: TextDocumentSyncKind = TextDocumentSyncKind.Incremental, ): if not issubclass(protocol_cls, asyncio.Protocol): raise TypeError("Protocol class should be subclass of asyncio.Protocol") @@ -207,9 +184,6 @@ def __init__( self._thread_pool: Optional[ThreadPool] = None self._thread_pool_executor: Optional[ThreadPoolExecutor] = None - if sync_kind is not None: - self.text_document_sync_kind = sync_kind - if loop is None: loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) @@ -218,9 +192,7 @@ def __init__( self._owns_loop = False self.loop = loop - - # TODO: Will move this to `LanguageServer` soon - self.lsp = protocol_cls(self, converter_factory()) # type: ignore + self.protocol = protocol_cls(self, converter_factory()) def shutdown(self): """Shutdown server.""" @@ -244,6 +216,21 @@ def shutdown(self): logger.info("Closing the event loop.") self.loop.close() + def _report_server_error( + self, + error: Exception, + source: ServerErrors, + ): + # Prevent recursive error reporting + try: + self.report_server_error(error, source) + except Exception: + logger.warning("Failed to report error") + + def report_server_error(self, error: Exception, source: ServerErrors): + """Default error reporter.""" + logger.error("%s", error) + def start_io(self, stdin: Optional[TextIO] = None, stdout: Optional[TextIO] = None): """Starts IO server.""" logger.info("Starting IO server") @@ -252,7 +239,7 @@ def start_io(self, stdin: Optional[TextIO] = None, stdout: Optional[TextIO] = No transport = StdOutTransportAdapter( stdin or sys.stdin.buffer, stdout or sys.stdout.buffer ) - self.lsp.connection_made(transport) # type: ignore[arg-type] + self.protocol.connection_made(transport) # type: ignore[arg-type] try: self.loop.run_until_complete( @@ -261,7 +248,7 @@ def start_io(self, stdin: Optional[TextIO] = None, stdout: Optional[TextIO] = No self.thread_pool_executor, self._stop_event, stdin or sys.stdin.buffer, - self.lsp.data_received, + self.protocol.data_received, ) ) except BrokenPipeError: @@ -277,8 +264,8 @@ def start_pyodide(self): # Note: We don't actually start anything running as the main event # loop will be handled by the web platform. transport = PyodideTransportAdapter(sys.stdout) - self.lsp.connection_made(transport) # type: ignore[arg-type] - self.lsp._send_only_body = True # Don't send headers within the payload + self.protocol.connection_made(transport) # type: ignore[arg-type] + self.protocol._send_only_body = True # Don't send headers within the payload def start_tcp(self, host: str, port: int) -> None: """Starts TCP server.""" @@ -286,7 +273,7 @@ def start_tcp(self, host: str, port: int) -> None: self._stop_event = Event() self._server = self.loop.run_until_complete( # type: ignore[assignment] - self.loop.create_server(self.lsp, host, port) + self.loop.create_server(self.protocol, host, port) ) try: self.loop.run_forever() @@ -306,14 +293,14 @@ def start_ws(self, host: str, port: int) -> None: logger.info("Starting WebSocket server on {}:{}".format(host, port)) self._stop_event = Event() - self.lsp._send_only_body = True # Don't send headers within the payload + self.protocol._send_only_body = True # Don't send headers within the payload async def connection_made(websocket, _): """Handle new connection wrapped in the WebSocket.""" - self.lsp.transport = WebSocketTransportAdapter(websocket, self.loop) + self.protocol.transport = WebSocketTransportAdapter(websocket, self.loop) async for message in websocket: - self.lsp._procedure_handler( - json.loads(message, object_hook=self.lsp._deserialize_message) + self.protocol._procedure_handler( + json.loads(message, object_hook=self.protocol._deserialize_message) ) start_server = serve(connection_made, host, port, loop=self.loop) @@ -328,113 +315,6 @@ async def connection_made(websocket, _): self._stop_event.set() self.shutdown() - if not IS_PYODIDE: - - @property - def thread_pool(self) -> ThreadPool: - """Returns thread pool instance (lazy initialization).""" - if not self._thread_pool: - self._thread_pool = ThreadPool(processes=self._max_workers) - - return self._thread_pool - - @property - def thread_pool_executor(self) -> ThreadPoolExecutor: - """Returns thread pool instance (lazy initialization).""" - if not self._thread_pool_executor: - self._thread_pool_executor = ThreadPoolExecutor( - max_workers=self._max_workers - ) - - return self._thread_pool_executor - - -class LanguageServer(Server): - """The default LanguageServer - - This class can be extended and it can be passed as a first argument to - registered commands/features. - - .. |ServerInfo| replace:: :class:`~lsprotocol.types.InitializeResultServerInfoType` - - Parameters - ---------- - name - Name of the server, used to populate |ServerInfo| which is sent to - the client during initialization - - version - Version of the server, used to populate |ServerInfo| which is sent to - the client during initialization - - protocol_cls - The :class:`~pygls.protocol.LanguageServerProtocol` class definition, or any - subclass of it. - - max_workers - Maximum number of workers for ``ThreadPool`` and ``ThreadPoolExecutor`` - - text_document_sync_kind - Text document synchronization method - - None - No synchronization - - :attr:`~lsprotocol.types.TextDocumentSyncKind.Full` - Send entire document text with each update - - :attr:`~lsprotocol.types.TextDocumentSyncKind.Incremental` - Send only the region of text that changed with each update - - notebook_document_sync - Advertise :lsp:`NotebookDocument` support to the client. - """ - - lsp: LanguageServerProtocol - - default_error_message = ( - "Unexpected error in LSP server, see server's logs for details" - ) - """ - The default error message sent to the user's editor when this server encounters an uncaught - exception. - """ - - def __init__( - self, - name: str, - version: str, - loop=None, - protocol_cls: Type[LanguageServerProtocol] = LanguageServerProtocol, - converter_factory=default_converter, - text_document_sync_kind: TextDocumentSyncKind = TextDocumentSyncKind.Incremental, - notebook_document_sync: Optional[NotebookDocumentSyncOptions] = None, - max_workers: int = 2, - ): - if not issubclass(protocol_cls, LanguageServerProtocol): - raise TypeError( - "Protocol class should be subclass of LanguageServerProtocol" - ) - - self.name = name - self.version = version - self._text_document_sync_kind = text_document_sync_kind - self._notebook_document_sync = notebook_document_sync - self.process_id: Optional[Union[int, None]] = None - super().__init__(protocol_cls, converter_factory, loop, max_workers) - - def apply_edit( - self, edit: WorkspaceEdit, label: Optional[str] = None - ) -> ApplyWorkspaceEditResponse: - """Sends apply edit request to the client.""" - return self.lsp.apply_edit(edit, label) - - def apply_edit_async( - self, edit: WorkspaceEdit, label: Optional[str] = None - ) -> ApplyWorkspaceEditResponse: - """Sends apply edit request to the client. Should be called with `await`""" - return self.lsp.apply_edit_async(edit, label) - def command(self, command_name: str) -> Callable[[F], F]: """Decorator used to register custom commands. @@ -446,17 +326,16 @@ def command(self, command_name: str) -> Callable[[F], F]: def my_cmd(ls, a, b, c): pass """ - return self.lsp.fm.command(command_name) + return self.protocol.fm.command(command_name) - @property - def client_capabilities(self) -> ClientCapabilities: - """The client's capabilities.""" - return self.lsp.client_capabilities + def thread(self) -> Callable[[F], F]: + """Decorator that mark function to execute it in a thread.""" + return self.protocol.fm.thread() def feature( self, feature_name: str, - options: Optional[Any] = None, + options: Any | None = None, ) -> Callable[[F], F]: """Decorator used to register LSP features. @@ -468,147 +347,24 @@ def feature( def completions(ls, params: CompletionParams): return CompletionList(is_incomplete=False, items=[CompletionItem("Completion 1")]) """ - return self.lsp.fm.feature(feature_name, options) + return self.protocol.fm.feature(feature_name, options) - def get_configuration( - self, - params: ConfigurationParams, - callback: Optional[ConfigCallbackType] = None, - ) -> Future: - """Gets the configuration settings from the client.""" - return self.lsp.get_configuration(params, callback) - - def get_configuration_async(self, params: ConfigurationParams) -> asyncio.Future: - """Gets the configuration settings from the client. Should be called with `await`""" - return self.lsp.get_configuration_async(params) - - def log_trace(self, message: str, verbose: Optional[str] = None) -> None: - """Sends trace notification to the client.""" - self.lsp.log_trace(message, verbose) - - @property - def progress(self) -> Progress: - """Gets the object to manage client's progress bar.""" - return self.lsp.progress - - def publish_diagnostics( - self, - uri: str, - diagnostics: Optional[List[Diagnostic]] = None, - version: Optional[int] = None, - **kwargs - ): - """ - Sends diagnostic notification to the client. - """ - params = self.lsp._construct_publish_diagnostic_type( - uri, diagnostics, version, **kwargs - ) - self.lsp.publish_diagnostics(params, **kwargs) - - def register_capability( - self, params: RegistrationParams, callback: Optional[Callable[[], None]] = None - ) -> Future: - """Register a new capability on the client.""" - return self.lsp.register_capability(params, callback) - - def register_capability_async(self, params: RegistrationParams) -> asyncio.Future: - """Register a new capability on the client. Should be called with `await`""" - return self.lsp.register_capability_async(params) - - def semantic_tokens_refresh( - self, callback: Optional[Callable[[], None]] = None - ) -> Future: - """Request a refresh of all semantic tokens.""" - return self.lsp.semantic_tokens_refresh(callback) - - def semantic_tokens_refresh_async(self) -> asyncio.Future: - """Request a refresh of all semantic tokens. Should be called with `await`""" - return self.lsp.semantic_tokens_refresh_async() - - def send_notification(self, method: str, params: object = None) -> None: - """Sends notification to the client.""" - self.lsp.notify(method, params) - - @property - def server_capabilities(self) -> ServerCapabilities: - """Return server capabilities.""" - return self.lsp.server_capabilities - - def show_document( - self, - params: ShowDocumentParams, - callback: Optional[ShowDocumentCallbackType] = None, - ) -> Future: - """Display a particular document in the user interface.""" - return self.lsp.show_document(params, callback) - - def show_document_async(self, params: ShowDocumentParams) -> asyncio.Future: - """Display a particular document in the user interface. Should be called with `await`""" - return self.lsp.show_document_async(params) - - def show_message(self, message, msg_type=MessageType.Info) -> None: - """Sends message to the client to display message.""" - self.lsp.show_message(message, msg_type) - - def show_message_log(self, message, msg_type=MessageType.Log) -> None: - """Sends message to the client's output channel.""" - self.lsp.show_message_log(message, msg_type) - - def _report_server_error( - self, - error: Exception, - source: ServerErrors, - ): - # Prevent recursive error reporting - try: - self.report_server_error(error, source) - except Exception: - logger.warning("Failed to report error to client") - - def report_server_error(self, error: Exception, source: ServerErrors): - """ - Sends error to the client for displaying. - - By default this function does not handle LSP request errors. This is because LSP requests - require direct responses and so already have a mechanism for including unexpected errors - in the response body. - - All other errors are "out of band" in the sense that the client isn't explicitly waiting - for them. For example diagnostics are returned as notifications, not responses to requests, - and so can seemingly be sent at random. Also for example consider JSON RPC serialization - and deserialization, if a payload cannot be parsed then the whole request/response cycle - cannot be completed and so one of these "out of band" error messages is sent. - - These "out of band" error messages are not a requirement of the LSP spec. Pygls simply - offers this behaviour as a recommended default. It is perfectly reasonble to override this - default. - """ + if not IS_PYODIDE: - if source == FeatureRequestError: - return + @property + def thread_pool(self) -> ThreadPool: + """Returns thread pool instance (lazy initialization).""" + if not self._thread_pool: + self._thread_pool = ThreadPool(processes=self._max_workers) - self.show_message(self.default_error_message, msg_type=MessageType.Error) + return self._thread_pool - def thread(self) -> Callable[[F], F]: - """Decorator that mark function to execute it in a thread.""" - return self.lsp.thread() + @property + def thread_pool_executor(self) -> ThreadPoolExecutor: + """Returns thread pool instance (lazy initialization).""" + if not self._thread_pool_executor: + self._thread_pool_executor = ThreadPoolExecutor( + max_workers=self._max_workers + ) - def unregister_capability( - self, - params: UnregistrationParams, - callback: Optional[Callable[[], None]] = None, - ) -> Future: - """Unregister a new capability on the client.""" - return self.lsp.unregister_capability(params, callback) - - def unregister_capability_async( - self, params: UnregistrationParams - ) -> asyncio.Future: - """Unregister a new capability on the client. Should be called with `await`""" - return self.lsp.unregister_capability_async(params) - - @property - def workspace(self) -> Workspace: - """Returns in-memory workspace.""" - return self.lsp.workspace + return self._thread_pool_executor From 8f2365f5010d82c6a2e7a1344ee87a1e35bd03a8 Mon Sep 17 00:00:00 2001 From: Alex Carney Date: Wed, 14 Aug 2024 20:17:36 +0100 Subject: [PATCH 4/9] chore: align to new server implementation --- README.md | 2 +- docs/source/user-guide.rst | 8 +- examples/hello-world/main.py | 2 +- examples/servers/code_actions.py | 3 +- examples/servers/code_lens.py | 12 +- examples/servers/colors.py | 3 +- examples/servers/formatting.py | 3 +- examples/servers/goto.py | 3 +- examples/servers/hover.py | 3 +- examples/servers/inlay_hints.py | 3 +- examples/servers/json_server.py | 292 +++++++++--------------- examples/servers/links.py | 2 +- examples/servers/publish_diagnostics.py | 19 +- examples/servers/pull_diagnostics.py | 3 +- examples/servers/rename.py | 3 +- examples/servers/semantic_tokens.py | 2 +- examples/servers/symbols.py | 3 +- 17 files changed, 160 insertions(+), 206 deletions(-) diff --git a/README.md b/README.md index 085efa81..ffc939f5 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ _pygls_ (pronounced like "pie glass") is a pythonic generic implementation of th ## Quickstart ```python -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer from lsprotocol.types import ( TEXT_DOCUMENT_COMPLETION, CompletionItem, diff --git a/docs/source/user-guide.rst b/docs/source/user-guide.rst index 4c6e2016..4e3e3c1b 100644 --- a/docs/source/user-guide.rst +++ b/docs/source/user-guide.rst @@ -30,7 +30,7 @@ The code snippet below shows how to start the server in *TCP* mode. .. code:: python - from pygls.server import LanguageServer + from pygls.lsp.server import LanguageServer server = LanguageServer('example-server', 'v0.1') @@ -48,7 +48,7 @@ The code snippet below shows how to start the server in *STDIO* mode. .. code:: python - from pygls.server import LanguageServer + from pygls.lsp.server import LanguageServer server = LanguageServer('example-server', 'v0.1') @@ -66,7 +66,7 @@ The code snippet below shows how to start the server in *WEBSOCKET* mode. .. code:: python - from pygls.server import LanguageServer + from pygls.lsp.server import LanguageServer server = LanguageServer('example-server', 'v0.1') @@ -89,7 +89,7 @@ is the minimal setup to setup logging in *pygls*: import logging - from pygls.server import LanguageServer + from pygls.lsp.server import LanguageServer logging.basicConfig(filename='pygls.log', filemode='w', level=logging.DEBUG) diff --git a/examples/hello-world/main.py b/examples/hello-world/main.py index 340e5611..b3970fcf 100644 --- a/examples/hello-world/main.py +++ b/examples/hello-world/main.py @@ -1,4 +1,4 @@ -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer from lsprotocol import types server = LanguageServer("example-server", "v0.1") diff --git a/examples/servers/code_actions.py b/examples/servers/code_actions.py index 989df818..5516d314 100644 --- a/examples/servers/code_actions.py +++ b/examples/servers/code_actions.py @@ -24,8 +24,9 @@ This server scans the document for incomplete sums e.g. ``1 + 1 =`` and returns a code action which, when invoked will fill in the answer. """ + import re -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer from lsprotocol.types import ( TEXT_DOCUMENT_CODE_ACTION, CodeAction, diff --git a/examples/servers/code_lens.py b/examples/servers/code_lens.py index 85af5687..dcbc7aad 100644 --- a/examples/servers/code_lens.py +++ b/examples/servers/code_lens.py @@ -28,12 +28,13 @@ front, this example demonstrates how the ``codeLens/resolve`` can be used to defer this computation until it is actually necessary. """ + import logging import re from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer ADDITION = re.compile(r"^\s*(\d+)\s*\+\s*(\d+)\s*=(?=\s*$)") server = LanguageServer("code-lens-server", "v1") @@ -115,7 +116,8 @@ def evaluate_sum(ls: LanguageServer, args): answer = arguments["left"] + arguments["right"] edit = types.TextDocumentEdit( text_document=types.OptionalVersionedTextDocumentIdentifier( - uri=arguments["uri"], version=document.version + uri=arguments["uri"], + version=document.version, ), edits=[ types.TextEdit( @@ -129,7 +131,11 @@ def evaluate_sum(ls: LanguageServer, args): ) # Apply the edit. - ls.apply_edit(types.WorkspaceEdit(document_changes=[edit])) + ls.workspace_apply_edit( + types.ApplyWorkspaceEditParams( + edit=types.WorkspaceEdit(document_changes=[edit]), + ), + ) if __name__ == "__main__": diff --git a/examples/servers/colors.py b/examples/servers/colors.py index 0e6cc206..28884c97 100644 --- a/examples/servers/colors.py +++ b/examples/servers/colors.py @@ -43,12 +43,13 @@ This server implements the requests defined above for CSS's hex color code syntax (``#000`` and ``#000000``). """ + import logging import re from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer COLOR = re.compile(r"""\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})(?!\w)""") server = LanguageServer("color-server", "v1") diff --git a/examples/servers/formatting.py b/examples/servers/formatting.py index ee7beffb..5c736d26 100644 --- a/examples/servers/formatting.py +++ b/examples/servers/formatting.py @@ -33,6 +33,7 @@ expect (fixes welcome!), but it should be enough to demonstrate the expected interaction between client and server. """ + import logging from typing import Dict from typing import List @@ -41,7 +42,7 @@ import attrs from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer from pygls.workspace import TextDocument diff --git a/examples/servers/goto.py b/examples/servers/goto.py index c77d5288..f2e081bf 100644 --- a/examples/servers/goto.py +++ b/examples/servers/goto.py @@ -32,12 +32,13 @@ This means the choices of what the example server below will return results for are completely arbitrary. """ + import logging import re from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer from pygls.workspace import TextDocument ARGUMENT = re.compile(r"(?P\w+): (?P\w+)") diff --git a/examples/servers/hover.py b/examples/servers/hover.py index fee94d3d..90aa3e5a 100644 --- a/examples/servers/hover.py +++ b/examples/servers/hover.py @@ -23,12 +23,13 @@ displaying a table how the selected date would be formatted in each of the supported formats. """ + import logging from datetime import datetime from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer DATE_FORMATS = [ "%H:%M:%S", diff --git a/examples/servers/inlay_hints.py b/examples/servers/inlay_hints.py index 6c143737..4e961090 100644 --- a/examples/servers/inlay_hints.py +++ b/examples/servers/inlay_hints.py @@ -28,11 +28,12 @@ uses the ``inlayHint/resolve`` to demonstrate how you can defer expensive computations to when they are required. """ + import re from typing import Optional from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer NUMBER = re.compile(r"\d+") server = LanguageServer("inlay-hint-server", "v1") diff --git a/examples/servers/json_server.py b/examples/servers/json_server.py index bc540037..1255d007 100644 --- a/examples/servers/json_server.py +++ b/examples/servers/json_server.py @@ -30,17 +30,17 @@ Eventually this example will be broken up in smaller, more focused examples and how to guides. """ + import argparse import asyncio -import json import time import uuid -from json import JSONDecodeError +from functools import partial from typing import Optional from lsprotocol import types as lsp -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer COUNT_DOWN_START_IN_SECONDS = 10 COUNT_DOWN_SLEEP_IN_SECONDS = 1 @@ -65,85 +65,6 @@ def __init__(self, *args): json_server = JsonLanguageServer("pygls-json-example", "v0.1") -def _validate(ls, params): - ls.show_message_log("Validating json...") - - text_doc = ls.workspace.get_document(params.text_document.uri) - - source = text_doc.source - diagnostics = _validate_json(source) if source else [] - - ls.publish_diagnostics(text_doc.uri, diagnostics) - - -def _validate_json(source): - """Validates json file.""" - diagnostics = [] - - try: - json.loads(source) - except JSONDecodeError as err: - msg = err.msg - col = err.colno - line = err.lineno - - d = lsp.Diagnostic( - range=lsp.Range( - start=lsp.Position(line=line - 1, character=col - 1), - end=lsp.Position(line=line - 1, character=col), - ), - message=msg, - source=type(json_server).__name__, - ) - - diagnostics.append(d) - - return diagnostics - - -@json_server.feature( - lsp.TEXT_DOCUMENT_DIAGNOSTIC, - lsp.DiagnosticOptions( - identifier="jsonServer", - inter_file_dependencies=True, - workspace_diagnostics=True, - ), -) -def text_document_diagnostic( - params: lsp.DocumentDiagnosticParams, -) -> lsp.DocumentDiagnosticReport: - """Returns diagnostic report.""" - document = json_server.workspace.get_document(params.text_document.uri) - return lsp.RelatedFullDocumentDiagnosticReport( - items=_validate_json(document.source), - kind=lsp.DocumentDiagnosticReportKind.Full, - ) - - -@json_server.feature(lsp.WORKSPACE_DIAGNOSTIC) -def workspace_diagnostic( - params: lsp.WorkspaceDiagnosticParams, -) -> lsp.WorkspaceDiagnosticReport: - """Returns diagnostic report.""" - documents = json_server.workspace.text_documents.keys() - - if len(documents) == 0: - items = [] - else: - first = list(documents)[0] - document = json_server.workspace.get_document(first) - items = [ - lsp.WorkspaceFullDocumentDiagnosticReport( - uri=document.uri, - version=document.version, - items=_validate_json(document.source), - kind=lsp.DocumentDiagnosticReportKind.Full, - ) - ] - - return lsp.WorkspaceDiagnosticReport(items=items) - - @json_server.feature( lsp.TEXT_DOCUMENT_COMPLETION, lsp.CompletionOptions(trigger_characters=[","], all_commit_characters=[":"]), @@ -163,76 +84,61 @@ def completions(params: Optional[lsp.CompletionParams] = None) -> lsp.Completion @json_server.command(JsonLanguageServer.CMD_COUNT_DOWN_BLOCKING) -def count_down_10_seconds_blocking(ls, *args): +def count_down_10_seconds_blocking(ls: JsonLanguageServer, *args): """Starts counting down and showing message synchronously. It will `block` the main thread, which can be tested by trying to show completion items. """ for i in range(COUNT_DOWN_START_IN_SECONDS): - ls.show_message(f"Counting down... {COUNT_DOWN_START_IN_SECONDS - i}") + ls.window_show_message( + lsp.ShowMessageParams( + message=f"Counting down... {COUNT_DOWN_START_IN_SECONDS - i}", + type=lsp.MessageType.Info, + ), + ) time.sleep(COUNT_DOWN_SLEEP_IN_SECONDS) @json_server.command(JsonLanguageServer.CMD_COUNT_DOWN_NON_BLOCKING) -async def count_down_10_seconds_non_blocking(ls, *args): +async def count_down_10_seconds_non_blocking(ls: JsonLanguageServer, *args): """Starts counting down and showing message asynchronously. It won't `block` the main thread, which can be tested by trying to show completion items. """ for i in range(COUNT_DOWN_START_IN_SECONDS): - ls.show_message(f"Counting down... {COUNT_DOWN_START_IN_SECONDS - i}") + ls.window_show_message( + lsp.ShowMessageParams( + message=f"Counting down... {COUNT_DOWN_START_IN_SECONDS - i}", + type=lsp.MessageType.Info, + ), + ) await asyncio.sleep(COUNT_DOWN_SLEEP_IN_SECONDS) -@json_server.feature(lsp.TEXT_DOCUMENT_DID_CHANGE) -def did_change(ls, params: lsp.DidChangeTextDocumentParams): - """Text document did change notification.""" - _validate(ls, params) - - -@json_server.feature(lsp.TEXT_DOCUMENT_DID_CLOSE) -def did_close(server: JsonLanguageServer, params: lsp.DidCloseTextDocumentParams): - """Text document did close notification.""" - server.show_message("Text Document Did Close") - - -@json_server.feature(lsp.TEXT_DOCUMENT_DID_OPEN) -async def did_open(ls, params: lsp.DidOpenTextDocumentParams): - """Text document did open notification.""" - ls.show_message("Text Document Did Open") - _validate(ls, params) - - -@json_server.feature(lsp.TEXT_DOCUMENT_INLINE_VALUE) -def inline_value(params: lsp.InlineValueParams): - """Returns inline value.""" - return [lsp.InlineValueText(range=params.range, text="Inline value")] - - @json_server.command(JsonLanguageServer.CMD_PROGRESS) async def progress(ls: JsonLanguageServer, *args): """Create and start the progress on the client.""" token = str(uuid.uuid4()) # Create - await ls.progress.create_async(token) + await ls.work_done_progress.create_async(token) # Begin - ls.progress.begin( + ls.work_done_progress.begin( token, lsp.WorkDoneProgressBegin(title="Indexing", percentage=0, cancellable=True), ) # Report for i in range(1, 10): # Check for cancellation from client - if ls.progress.tokens[token].cancelled(): + if ls.work_done_progress.tokens[token].cancelled(): # ... and stop the computation if client cancelled return - ls.progress.report( + ls.work_done_progress.report( token, lsp.WorkDoneProgressReport(message=f"{i * 10}%", percentage=i * 10), ) await asyncio.sleep(2) # End - ls.progress.end(token, lsp.WorkDoneProgressEnd(message="Finished")) + ls.work_done_progress.end(token, lsp.WorkDoneProgressEnd(message="Finished")) @json_server.command(JsonLanguageServer.CMD_REGISTER_COMPLETIONS) @@ -247,59 +153,104 @@ async def register_completions(ls: JsonLanguageServer, *args): ) ] ) - response = await ls.register_capability_async(params) - if response is None: - ls.show_message("Successfully registered completions method") - else: - ls.show_message( - "Error happened during completions registration.", lsp.MessageType.Error + + try: + await ls.client_register_capability_async(params) + ls.window_show_message( + lsp.ShowMessageParams( + message="Successfully registered completions method", + type=lsp.MessageType.Info, + ), + ) + except Exception: + ls.window_show_message( + lsp.ShowMessageParams( + message="Error happened during completions registration.", + type=lsp.MessageType.Error, + ), ) -@json_server.command(JsonLanguageServer.CMD_SHOW_CONFIGURATION_ASYNC) -async def show_configuration_async(ls: JsonLanguageServer, *args): - """Gets exampleConfiguration from the client settings using coroutines.""" +@json_server.command(JsonLanguageServer.CMD_UNREGISTER_COMPLETIONS) +async def unregister_completions(ls: JsonLanguageServer, *args): + """Unregister completions method on the client.""" + params = lsp.UnregistrationParams( + unregisterations=[ + lsp.Unregistration( + id=str(uuid.uuid4()), + method=lsp.TEXT_DOCUMENT_COMPLETION, + ), + ], + ) + try: - config = await ls.get_configuration_async( - lsp.ConfigurationParams( - items=[ - lsp.ConfigurationItem( - scope_uri="", section=JsonLanguageServer.CONFIGURATION_SECTION - ) - ] - ) + await ls.client_unregister_capability_async(params) + ls.window_show_message( + lsp.ShowMessageParams( + message="Successfully unregistered completions method", + type=lsp.MessageType.Info, + ), + ) + except Exception: + ls.window_show_message( + lsp.ShowMessageParams( + message="Error happened during completions unregistration.", + type=lsp.MessageType.Error, + ), ) + +def handle_config(ls: JsonLanguageServer, config): + """Handle the configuration sent by the client.""" + try: example_config = config[0].get("exampleConfiguration") - ls.show_message(f"jsonServer.exampleConfiguration value: {example_config}") + ls.window_show_message( + lsp.ShowMessageParams( + message=f"jsonServer.exampleConfiguration value: {example_config}", + type=lsp.MessageType.Info, + ), + ) except Exception as e: - ls.show_message_log(f"Error ocurred: {e}") + ls.window_log_message( + lsp.LogMessageParams( + message=f"Error ocurred: {e}", + type=lsp.MessageType.Error, + ), + ) + + +@json_server.command(JsonLanguageServer.CMD_SHOW_CONFIGURATION_ASYNC) +async def show_configuration_async(ls: JsonLanguageServer, *args): + """Gets exampleConfiguration from the client settings using coroutines.""" + config = await ls.workspace_configuration_async( + lsp.ConfigurationParams( + items=[ + lsp.ConfigurationItem( + scope_uri="", + section=JsonLanguageServer.CONFIGURATION_SECTION, + ), + ] + ) + ) + handle_config(ls, config) @json_server.command(JsonLanguageServer.CMD_SHOW_CONFIGURATION_CALLBACK) def show_configuration_callback(ls: JsonLanguageServer, *args): """Gets exampleConfiguration from the client settings using callback.""" - def _config_callback(config): - try: - example_config = config[0].get("exampleConfiguration") - - ls.show_message(f"jsonServer.exampleConfiguration value: {example_config}") - - except Exception as e: - ls.show_message_log(f"Error ocurred: {e}") - - ls.get_configuration( + ls.workspace_configuration( lsp.ConfigurationParams( items=[ lsp.ConfigurationItem( - scope_uri="", section=JsonLanguageServer.CONFIGURATION_SECTION - ) + scope_uri="", + section=JsonLanguageServer.CONFIGURATION_SECTION, + ), ] ), - _config_callback, + callback=partial(handle_config, ls), ) @@ -307,42 +258,17 @@ def _config_callback(config): @json_server.command(JsonLanguageServer.CMD_SHOW_CONFIGURATION_THREAD) def show_configuration_thread(ls: JsonLanguageServer, *args): """Gets exampleConfiguration from the client settings using thread pool.""" - try: - config = ls.get_configuration( - lsp.ConfigurationParams( - items=[ - lsp.ConfigurationItem( - scope_uri="", section=JsonLanguageServer.CONFIGURATION_SECTION - ) - ] - ) - ).result(2) - - example_config = config[0].get("exampleConfiguration") - - ls.show_message(f"jsonServer.exampleConfiguration value: {example_config}") - - except Exception as e: - ls.show_message_log(f"Error ocurred: {e}") - - -@json_server.command(JsonLanguageServer.CMD_UNREGISTER_COMPLETIONS) -async def unregister_completions(ls: JsonLanguageServer, *args): - """Unregister completions method on the client.""" - params = lsp.UnregistrationParams( - unregisterations=[ - lsp.Unregistration( - id=str(uuid.uuid4()), method=lsp.TEXT_DOCUMENT_COMPLETION - ) - ] - ) - response = await ls.unregister_capability_async(params) - if response is None: - ls.show_message("Successfully unregistered completions method") - else: - ls.show_message( - "Error happened during completions unregistration.", lsp.MessageType.Error + config = ls.workspace_configuration( + lsp.ConfigurationParams( + items=[ + lsp.ConfigurationItem( + scope_uri="", + section=JsonLanguageServer.CONFIGURATION_SECTION, + ), + ], ) + ).result(2) + handle_config(ls, config) def add_arguments(parser): diff --git a/examples/servers/links.py b/examples/servers/links.py index 8857d196..99bacddb 100644 --- a/examples/servers/links.py +++ b/examples/servers/links.py @@ -33,7 +33,7 @@ from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer LINK = re.compile(r"<(\w+):([^>]+)>") server = LanguageServer("links-server", "v1") diff --git a/examples/servers/publish_diagnostics.py b/examples/servers/publish_diagnostics.py index 9e887dbf..3eb8ef6b 100644 --- a/examples/servers/publish_diagnostics.py +++ b/examples/servers/publish_diagnostics.py @@ -24,12 +24,13 @@ This server scans a document for sums e.g. ``1 + 2 = 3``, highlighting any that are either missing answers (warnings) or incorrect (errors). """ + import logging import re from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer from pygls.workspace import TextDocument ADDITION = re.compile(r"^\s*(\d+)\s*\+\s*(\d+)\s*=\s*(\d+)?$") @@ -89,7 +90,13 @@ def did_open(ls: PublishDiagnosticServer, params: types.DidOpenTextDocumentParam ls.parse(doc) for uri, (version, diagnostics) in ls.diagnostics.items(): - ls.publish_diagnostics(uri=uri, version=version, diagnostics=diagnostics) + ls.text_document_publish_diagnostics( + types.PublishDiagnosticsParams( + uri=uri, + version=version, + diagnostics=diagnostics, + ) + ) @server.feature(types.TEXT_DOCUMENT_DID_CHANGE) @@ -99,7 +106,13 @@ def did_change(ls: PublishDiagnosticServer, params: types.DidOpenTextDocumentPar ls.parse(doc) for uri, (version, diagnostics) in ls.diagnostics.items(): - ls.publish_diagnostics(uri=uri, version=version, diagnostics=diagnostics) + ls.text_document_publish_diagnostics( + types.PublishDiagnosticsParams( + uri=uri, + version=version, + diagnostics=diagnostics, + ) + ) if __name__ == "__main__": diff --git a/examples/servers/pull_diagnostics.py b/examples/servers/pull_diagnostics.py index 637f347f..b33e77fe 100644 --- a/examples/servers/pull_diagnostics.py +++ b/examples/servers/pull_diagnostics.py @@ -26,12 +26,13 @@ This server scans a document for sums e.g. ``1 + 2 = 3``, highlighting any that are either missing answers (warnings) or incorrect (errors). """ + import logging import re from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer from pygls.workspace import TextDocument ADDITION = re.compile(r"^\s*(\d+)\s*\+\s*(\d+)\s*=\s*(\d+)?$") diff --git a/examples/servers/rename.py b/examples/servers/rename.py index c27314f4..e0c1fc29 100644 --- a/examples/servers/rename.py +++ b/examples/servers/rename.py @@ -29,13 +29,14 @@ a real server would have to check to make sure it only renames symbols in the relevant scope. """ + import logging import re from typing import List from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer from pygls.workspace import TextDocument ARGUMENT = re.compile(r"(?P\w+): (?P\w+)") diff --git a/examples/servers/semantic_tokens.py b/examples/servers/semantic_tokens.py index 54e2c3ba..7c446181 100644 --- a/examples/servers/semantic_tokens.py +++ b/examples/servers/semantic_tokens.py @@ -42,7 +42,7 @@ import attrs from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer from pygls.workspace import TextDocument diff --git a/examples/servers/symbols.py b/examples/servers/symbols.py index 5ff76cba..4d0a7fbf 100644 --- a/examples/servers/symbols.py +++ b/examples/servers/symbols.py @@ -33,12 +33,13 @@ .. literalinclude:: ../../../examples/servers/workspace/code.txt :language: none """ + import logging import re from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer from pygls.workspace import TextDocument ARGUMENT = re.compile(r"(?P\w+)(: ?(?P\w+))?") From 358a5bed5072cbd1babc156abc19ccdfed381216 Mon Sep 17 00:00:00 2001 From: Alex Carney Date: Wed, 14 Aug 2024 20:19:17 +0100 Subject: [PATCH 5/9] chore: align tests with new server implementation --- tests/e2e/test_inline_value.py | 71 -------------------------- tests/ls_setup.py | 22 ++++---- tests/lsp/test_call_hierarchy.py | 8 +-- tests/lsp/test_document_highlight.py | 4 +- tests/lsp/test_errors.py | 25 +++++---- tests/lsp/test_folding_range.py | 4 +- tests/lsp/test_linked_editing_range.py | 4 +- tests/lsp/test_moniker.py | 4 +- tests/lsp/test_progress.py | 24 ++++----- tests/lsp/test_selection_range.py | 4 +- tests/lsp/test_signature_help.py | 4 +- tests/lsp/test_type_hierarchy.py | 8 +-- tests/test_language_server.py | 18 +++---- tests/test_protocol.py | 28 +++++----- tests/test_server_connection.py | 14 ++--- 15 files changed, 88 insertions(+), 154 deletions(-) delete mode 100644 tests/e2e/test_inline_value.py diff --git a/tests/e2e/test_inline_value.py b/tests/e2e/test_inline_value.py deleted file mode 100644 index d0636f11..00000000 --- a/tests/e2e/test_inline_value.py +++ /dev/null @@ -1,71 +0,0 @@ -############################################################################ -# Copyright(c) Open Law Library. All rights reserved. # -# See ThirdPartyNotices.txt in the project root for additional notices. # -# # -# Licensed under the Apache License, Version 2.0 (the "License") # -# you may not use this file except in compliance with the License. # -# You may obtain a copy of the License at # -# # -# http: // www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -############################################################################ -from __future__ import annotations - -import typing - -import pytest_asyncio -from lsprotocol import types - -if typing.TYPE_CHECKING: - from typing import Tuple - - from pygls.lsp.client import BaseLanguageClient - - -@pytest_asyncio.fixture() -async def json_server(get_client_for): - async for result in get_client_for("json_server.py"): - yield result - - -async def test_inline_value( - json_server: Tuple[BaseLanguageClient, types.InitializeResult], - uri_for, -): - """Ensure that inline values are working as expected.""" - client, _ = json_server - - test_uri = uri_for("test.json") - assert test_uri is not None - - document_content = '{\n"foo": "bar"\n}' - client.text_document_did_open( - types.DidOpenTextDocumentParams( - text_document=types.TextDocumentItem( - uri=test_uri, language_id="json", version=1, text=document_content - ) - ) - ) - - result = await client.text_document_inline_value_async( - types.InlineValueParams( - text_document=types.TextDocumentIdentifier(test_uri), - range=types.Range( - start=types.Position(line=1, character=0), - end=types.Position(line=1, character=6), - ), - context=types.InlineValueContext( - frame_id=1, - stopped_location=types.Range( - start=types.Position(line=1, character=0), - end=types.Position(line=1, character=6), - ), - ), - ) - ) - assert result[0].text == "Inline value" diff --git a/tests/ls_setup.py b/tests/ls_setup.py index 7c3bfb53..1ad5b736 100644 --- a/tests/ls_setup.py +++ b/tests/ls_setup.py @@ -27,7 +27,7 @@ ClientCapabilities, InitializeParams, ) -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer from . import CMD_ASYNC, CMD_SYNC, CMD_THREAD @@ -62,8 +62,8 @@ def __init__(self, dest: LanguageServer): def close(self): ... def write(self, data): - object_hook = self.dest.lsp._deserialize_message - self.dest.lsp._procedure_handler(json.loads(data, object_hook=object_hook)) + object_hook = self.dest.protocol._deserialize_message + self.dest.protocol._procedure_handler(json.loads(data, object_hook=object_hook)) class PyodideClientServer: @@ -74,11 +74,11 @@ def __init__(self, LS=LanguageServer): self.server = LS("pygls-server", "v1") self.client = LS("pygls-client", "v1") - self.server.lsp.connection_made(PyodideTestTransportAdapter(self.client)) - self.server.lsp._send_only_body = True + self.server.protocol.connection_made(PyodideTestTransportAdapter(self.client)) + self.server.protocol._send_only_body = True - self.client.lsp.connection_made(PyodideTestTransportAdapter(self.server)) - self.client.lsp._send_only_body = True + self.client.protocol.connection_made(PyodideTestTransportAdapter(self.server)) + self.client.protocol._send_only_body = True def start(self): self.initialize() @@ -90,7 +90,7 @@ def decorate(cls): return pytest.mark.parametrize("client_server", [cls], indirect=True) def initialize(self): - response = self.client.lsp.send_request( + response = self.client.protocol.send_request( INITIALIZE, InitializeParams( process_id=12345, root_uri="file://", capabilities=ClientCapabilities() @@ -140,9 +140,9 @@ def start(self): self.initialize() def stop(self): - shutdown_response = self.client.lsp.send_request(SHUTDOWN).result() + shutdown_response = self.client.protocol.send_request(SHUTDOWN).result() assert shutdown_response is None - self.client.lsp.notify(EXIT) + self.client.protocol.notify(EXIT) self.server_thread.join() self.client._stop_event.set() try: @@ -154,7 +154,7 @@ def stop(self): @retry_stalled_init_fix_hack() def initialize(self): timeout = None if "DISABLE_TIMEOUT" in os.environ else 1 - response = self.client.lsp.send_request( + response = self.client.protocol.send_request( INITIALIZE, InitializeParams( process_id=12345, root_uri="file://", capabilities=ClientCapabilities() diff --git a/tests/lsp/test_call_hierarchy.py b/tests/lsp/test_call_hierarchy.py index 410a9827..1353cb39 100644 --- a/tests/lsp/test_call_hierarchy.py +++ b/tests/lsp/test_call_hierarchy.py @@ -131,7 +131,7 @@ def test_capabilities(client_server): @ConfiguredLS.decorate() def test_call_hierarchy_prepare_return_list(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( TEXT_DOCUMENT_PREPARE_CALL_HIERARCHY, CallHierarchyPrepareParams( text_document=TextDocumentIdentifier(uri="file://return.list"), @@ -145,7 +145,7 @@ def test_call_hierarchy_prepare_return_list(client_server): @ConfiguredLS.decorate() def test_call_hierarchy_prepare_return_none(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( TEXT_DOCUMENT_PREPARE_CALL_HIERARCHY, CallHierarchyPrepareParams( text_document=TextDocumentIdentifier(uri="file://return.none"), @@ -159,7 +159,7 @@ def test_call_hierarchy_prepare_return_none(client_server): @ConfiguredLS.decorate() def test_call_hierarchy_incoming_calls_return_list(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( CALL_HIERARCHY_INCOMING_CALLS, CallHierarchyIncomingCallsParams(item=CALL_HIERARCHY_ITEM), ).result() @@ -177,7 +177,7 @@ def test_call_hierarchy_incoming_calls_return_list(client_server): @ConfiguredLS.decorate() def test_call_hierarchy_outgoing_calls_return_list(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( CALL_HIERARCHY_OUTGOING_CALLS, CallHierarchyOutgoingCallsParams(item=CALL_HIERARCHY_ITEM), ).result() diff --git a/tests/lsp/test_document_highlight.py b/tests/lsp/test_document_highlight.py index e4afc5fe..2439a579 100644 --- a/tests/lsp/test_document_highlight.py +++ b/tests/lsp/test_document_highlight.py @@ -71,7 +71,7 @@ def test_capabilities(client_server): @ConfiguredLS.decorate() def test_document_highlight_return_list(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( TEXT_DOCUMENT_DOCUMENT_HIGHLIGHT, DocumentHighlightParams( text_document=TextDocumentIdentifier(uri="file://return.list"), @@ -97,7 +97,7 @@ def test_document_highlight_return_list(client_server): @ConfiguredLS.decorate() def test_document_highlight_return_none(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( TEXT_DOCUMENT_DOCUMENT_HIGHLIGHT, DocumentHighlightParams( text_document=TextDocumentIdentifier(uri="file://return.none"), diff --git a/tests/lsp/test_errors.py b/tests/lsp/test_errors.py index 1fbc05b4..fdd38c51 100644 --- a/tests/lsp/test_errors.py +++ b/tests/lsp/test_errors.py @@ -19,10 +19,10 @@ import time import pytest +from lsprotocol import types from pygls.exceptions import JsonRpcInternalError, PyglsError, JsonRpcException -from lsprotocol.types import WINDOW_SHOW_MESSAGE, MessageType -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer from ..conftest import ClientServer @@ -48,7 +48,12 @@ class CustomLanguageServerSendAll(LanguageServer): def report_server_error( self, error: Exception, source: Union[PyglsError, JsonRpcException] ): - self.show_message(self.default_error_message, msg_type=MessageType.Error) + self.window_show_message( + types.ShowMessageParams( + message="Error in LSP server", + type=types.MessageType.Error, + ), + ) class ConfiguredLS(ClientServer): @@ -63,7 +68,7 @@ def init(self): def f1(params: Any): raise Exception(ERROR_MESSAGE) - @self.client.feature(WINDOW_SHOW_MESSAGE) + @self.client.feature(types.WINDOW_SHOW_MESSAGE) def f2(params: Any): self.client.messages.append(params.message) @@ -89,7 +94,7 @@ def test_request_error_reporting_default(client_server): assert len(client.messages) == 0 with pytest.raises(JsonRpcInternalError, match=ERROR_MESSAGE): - client.lsp.send_request(ERROR_TRIGGER).result() + client.protocol.send_request(ERROR_TRIGGER).result() time.sleep(0.1) assert len(client.messages) == 0 @@ -101,7 +106,7 @@ def test_request_error_reporting_override(client_server): assert len(client.messages) == 0 with pytest.raises(JsonRpcInternalError, match=ERROR_MESSAGE): - client.lsp.send_request(ERROR_TRIGGER).result() + client.protocol.send_request(ERROR_TRIGGER).result() time.sleep(0.1) assert len(client.messages) == 1 @@ -110,17 +115,17 @@ def test_request_error_reporting_override(client_server): @ConfiguredLS.decorate() def test_notification_error_reporting(client_server): client, _ = client_server - client.lsp.notify(ERROR_TRIGGER) + client.protocol.notify(ERROR_TRIGGER) time.sleep(0.1) assert len(client.messages) == 1 - assert client.messages[0] == LanguageServer.default_error_message + assert client.messages[0].startswith("Error in server:") @CustomConfiguredLSSafe.decorate() def test_overriding_error_reporting(client_server): client, _ = client_server - client.lsp.notify(ERROR_TRIGGER) + client.protocol.notify(ERROR_TRIGGER) time.sleep(0.1) assert len(client.messages) == 0 @@ -129,7 +134,7 @@ def test_overriding_error_reporting(client_server): @CustomConfiguredLSPotentialRecusrion.decorate() def test_overriding_error_reporting_with_potential_recursion(client_server): client, _ = client_server - client.lsp.notify(ERROR_TRIGGER) + client.protocol.notify(ERROR_TRIGGER) time.sleep(0.1) assert len(client.messages) == 0 diff --git a/tests/lsp/test_folding_range.py b/tests/lsp/test_folding_range.py index 8f9c749a..c3b13963 100644 --- a/tests/lsp/test_folding_range.py +++ b/tests/lsp/test_folding_range.py @@ -63,7 +63,7 @@ def test_capabilities(client_server): @ConfiguredLS.decorate() def test_folding_range_return_list(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( TEXT_DOCUMENT_FOLDING_RANGE, FoldingRangeParams( text_document=TextDocumentIdentifier(uri="file://return.list"), @@ -82,7 +82,7 @@ def test_folding_range_return_list(client_server): @ConfiguredLS.decorate() def test_folding_range_return_none(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( TEXT_DOCUMENT_FOLDING_RANGE, FoldingRangeParams( text_document=TextDocumentIdentifier(uri="file://return.none"), diff --git a/tests/lsp/test_linked_editing_range.py b/tests/lsp/test_linked_editing_range.py index 2650b7eb..d3743671 100644 --- a/tests/lsp/test_linked_editing_range.py +++ b/tests/lsp/test_linked_editing_range.py @@ -68,7 +68,7 @@ def test_capabilities(client_server): @ConfiguredLS.decorate() def test_linked_editing_ranges_return_ranges(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( TEXT_DOCUMENT_LINKED_EDITING_RANGE, LinkedEditingRangeParams( text_document=TextDocumentIdentifier(uri="file://return.ranges"), @@ -92,7 +92,7 @@ def test_linked_editing_ranges_return_ranges(client_server): @ConfiguredLS.decorate() def test_linked_editing_ranges_return_none(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( TEXT_DOCUMENT_LINKED_EDITING_RANGE, LinkedEditingRangeParams( text_document=TextDocumentIdentifier(uri="file://return.none"), diff --git a/tests/lsp/test_moniker.py b/tests/lsp/test_moniker.py index 09b962d6..a061f59b 100644 --- a/tests/lsp/test_moniker.py +++ b/tests/lsp/test_moniker.py @@ -64,7 +64,7 @@ def test_capabilities(client_server): @ConfiguredLS.decorate() def test_moniker_return_list(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( TEXT_DOCUMENT_MONIKER, MonikerParams( text_document=TextDocumentIdentifier(uri="file://return.list"), @@ -83,7 +83,7 @@ def test_moniker_return_list(client_server): @ConfiguredLS.decorate() def test_references_return_none(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( TEXT_DOCUMENT_MONIKER, MonikerParams( text_document=TextDocumentIdentifier(uri="file://return.none"), diff --git a/tests/lsp/test_progress.py b/tests/lsp/test_progress.py index 49657729..79cf3558 100644 --- a/tests/lsp/test_progress.py +++ b/tests/lsp/test_progress.py @@ -58,30 +58,30 @@ async def f1(params: CodeLensParams) -> Optional[List[CodeLens]]: assert "server_initiated_token" in params.text_document.uri token = params.text_document.uri[len("file://") :] if "async" in params.text_document.uri: - await self.server.progress.create_async(token) + await self.server.work_done_progress.create_async(token) else: - f = self.server.progress.create(token) + f = self.server.work_done_progress.create(token) await asyncio.sleep(0.1) f.result() assert token - self.server.lsp.progress.begin( + self.server.protocol.progress.begin( token, WorkDoneProgressBegin(kind="begin", title="starting", percentage=0), ) await asyncio.sleep(0.1) - if self.server.lsp.progress.tokens[token].cancelled(): - self.server.lsp.progress.end( + if self.server.protocol.progress.tokens[token].cancelled(): + self.server.protocol.progress.end( token, WorkDoneProgressEnd(kind="end", message="cancelled") ) else: - self.server.lsp.progress.report( + self.server.protocol.progress.report( token, WorkDoneProgressReport( kind="report", message="doing", percentage=50 ), ) - self.server.lsp.progress.end( + self.server.protocol.progress.end( token, WorkDoneProgressEnd(kind="end", message="done") ) return None @@ -91,7 +91,7 @@ def f2(params): self.client.notifications.append(params) if params.value["kind"] == "begin" and "cancel" in params.token: # client cancels the progress token - self.client.lsp.notify( + self.client.protocol.notify( WINDOW_WORK_DONE_PROGRESS_CANCEL, WorkDoneProgressCancelParams(token=params.token), ) @@ -115,7 +115,7 @@ def test_capabilities(client_server): @ConfiguredLS.decorate() async def test_progress_notifications(client_server): client, _ = client_server - client.lsp.send_request( + client.protocol.send_request( TEXT_DOCUMENT_CODE_LENS, CodeLensParams( text_document=TextDocumentIdentifier(uri="file://client_initiated_token"), @@ -144,7 +144,7 @@ async def test_progress_notifications(client_server): @ConfiguredLS.decorate() async def test_server_initiated_progress_notifications(client_server, registration): client, _ = client_server - client.lsp.send_request( + client.protocol.send_request( TEXT_DOCUMENT_CODE_LENS, CodeLensParams( text_document=TextDocumentIdentifier( @@ -179,7 +179,7 @@ async def test_server_initiated_progress_notifications(client_server, registrati @ConfiguredLS.decorate() def test_progress_cancel_notifications(client_server): client, _ = client_server - client.lsp.send_request( + client.protocol.send_request( TEXT_DOCUMENT_CODE_LENS, CodeLensParams( text_document=TextDocumentIdentifier(uri="file://client_initiated_token"), @@ -206,7 +206,7 @@ def test_server_initiated_progress_progress_cancel_notifications( client_server, registration ): client, _ = client_server - client.lsp.send_request( + client.protocol.send_request( TEXT_DOCUMENT_CODE_LENS, CodeLensParams( text_document=TextDocumentIdentifier( diff --git a/tests/lsp/test_selection_range.py b/tests/lsp/test_selection_range.py index 5f669a20..7b05a55e 100644 --- a/tests/lsp/test_selection_range.py +++ b/tests/lsp/test_selection_range.py @@ -70,7 +70,7 @@ def test_capabilities(client_server): @ConfiguredLS.decorate() def test_selection_range_return_list(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( TEXT_DOCUMENT_SELECTION_RANGE, SelectionRangeParams( # query="query", @@ -98,7 +98,7 @@ def test_selection_range_return_list(client_server): @ConfiguredLS.decorate() def test_selection_range_return_none(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( TEXT_DOCUMENT_SELECTION_RANGE, SelectionRangeParams( # query="query", diff --git a/tests/lsp/test_signature_help.py b/tests/lsp/test_signature_help.py index e3181203..cde13985 100644 --- a/tests/lsp/test_signature_help.py +++ b/tests/lsp/test_signature_help.py @@ -83,7 +83,7 @@ def test_capabilities(client_server): @pytest.mark.skip def test_signature_help_return_signature_help(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( TEXT_DOCUMENT_SIGNATURE_HELP, SignatureHelpParams( text_document=TextDocumentIdentifier(uri="file://return.signature_help"), @@ -129,7 +129,7 @@ def test_signature_help_return_signature_help(client_server): @pytest.mark.skip def test_signature_help_return_none(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( TEXT_DOCUMENT_SIGNATURE_HELP, SignatureHelpParams( text_document=TextDocumentIdentifier(uri="file://return.none"), diff --git a/tests/lsp/test_type_hierarchy.py b/tests/lsp/test_type_hierarchy.py index e186c7f5..78e8e97f 100644 --- a/tests/lsp/test_type_hierarchy.py +++ b/tests/lsp/test_type_hierarchy.py @@ -80,7 +80,7 @@ def test_capabilities(client_server): @ConfiguredLS.decorate() def test_type_hierarchy_prepare_return_list(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( lsp.TEXT_DOCUMENT_PREPARE_TYPE_HIERARCHY, lsp.TypeHierarchyPrepareParams( text_document=lsp.TextDocumentIdentifier(uri="file://return.list"), @@ -94,7 +94,7 @@ def test_type_hierarchy_prepare_return_list(client_server): @ConfiguredLS.decorate() def test_type_hierarchy_prepare_return_none(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( lsp.TEXT_DOCUMENT_PREPARE_TYPE_HIERARCHY, lsp.TypeHierarchyPrepareParams( text_document=lsp.TextDocumentIdentifier(uri="file://return.none"), @@ -108,7 +108,7 @@ def test_type_hierarchy_prepare_return_none(client_server): @ConfiguredLS.decorate() def test_type_hierarchy_supertypes(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( lsp.TYPE_HIERARCHY_SUPERTYPES, lsp.TypeHierarchySupertypesParams(item=TYPE_HIERARCHY_ITEM), ).result() @@ -119,7 +119,7 @@ def test_type_hierarchy_supertypes(client_server): @ConfiguredLS.decorate() def test_type_hierarchy_subtypes(client_server): client, _ = client_server - response = client.lsp.send_request( + response = client.protocol.send_request( lsp.TYPE_HIERARCHY_SUBTYPES, lsp.TypeHierarchySubtypesParams(item=TYPE_HIERARCHY_ITEM), ).result() diff --git a/tests/test_language_server.py b/tests/test_language_server.py index 5271ff58..7725eadc 100644 --- a/tests/test_language_server.py +++ b/tests/test_language_server.py @@ -33,12 +33,12 @@ TextDocumentItem, ) from pygls.protocol import LanguageServerProtocol -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer from . import CMD_ASYNC, CMD_SYNC, CMD_THREAD def _initialize_server(server): - server.lsp.lsp_initialize( + server.protocol.lsp_initialize( InitializeParams( process_id=1234, root_uri=pathlib.Path(__file__).parent.as_uri(), @@ -52,7 +52,7 @@ def test_bf_initialize(client_server): root_uri = pathlib.Path(__file__).parent.as_uri() process_id = 1234 - response = client.lsp.send_request( + response = client.protocol.send_request( INITIALIZE, InitializeParams( process_id=process_id, @@ -71,7 +71,7 @@ def test_bf_text_document_did_open(client_server): _initialize_server(server) - client.lsp.notify( + client.protocol.notify( TEXT_DOCUMENT_DID_OPEN, DidOpenTextDocumentParams( text_document=TextDocumentItem( @@ -82,7 +82,7 @@ def test_bf_text_document_did_open(client_server): sleep(1) - assert len(server.lsp.workspace.text_documents) == 1 + assert len(server.protocol.workspace.text_documents) == 1 document = server.workspace.get_text_document(__file__) assert document.uri == __file__ @@ -95,7 +95,7 @@ def test_bf_text_document_did_open(client_server): def test_command_async(client_server): client, server = client_server - is_called, thread_id = client.lsp.send_request( + is_called, thread_id = client.protocol.send_request( WORKSPACE_EXECUTE_COMMAND, ExecuteCommandParams(command=CMD_ASYNC) ).result() @@ -107,7 +107,7 @@ def test_command_async(client_server): def test_command_sync(client_server): client, server = client_server - is_called, thread_id = client.lsp.send_request( + is_called, thread_id = client.protocol.send_request( WORKSPACE_EXECUTE_COMMAND, ExecuteCommandParams(command=CMD_SYNC) ).result() @@ -119,7 +119,7 @@ def test_command_sync(client_server): def test_command_thread(client_server): client, server = client_server - is_called, thread_id = client.lsp.send_request( + is_called, thread_id = client.protocol.send_request( WORKSPACE_EXECUTE_COMMAND, ExecuteCommandParams(command=CMD_THREAD) ).result() @@ -133,7 +133,7 @@ class CustomProtocol(LanguageServerProtocol): server = LanguageServer("pygls-test", "v1", protocol_cls=CustomProtocol) - assert isinstance(server.lsp, CustomProtocol) + assert isinstance(server.protocol, CustomProtocol) def test_forbid_custom_protocol_not_derived_from_lsp(): diff --git a/tests/test_protocol.py b/tests/test_protocol.py index 58d53aef..bc73e370 100644 --- a/tests/test_protocol.py +++ b/tests/test_protocol.py @@ -544,7 +544,7 @@ def test_data_received_without_content_type(client_server): ) ) data = bytes(message, "utf-8") - server.lsp.data_received(data) + server.protocol.data_received(data) def test_data_received_content_type_first_should_handle_message(client_server): @@ -565,7 +565,7 @@ def test_data_received_content_type_first_should_handle_message(client_server): ) ) data = bytes(message, "utf-8") - server.lsp.data_received(data) + server.protocol.data_received(data) def dummy_message(param=1): @@ -590,22 +590,22 @@ def dummy_message(param=1): def test_data_received_single_message_should_handle_message(client_server): _, server = client_server data = dummy_message() - server.lsp.data_received(data) + server.protocol.data_received(data) def test_data_received_partial_message_should_handle_message(client_server): _, server = client_server data = dummy_message() partial = len(data) - 5 - server.lsp.data_received(data[:partial]) - server.lsp.data_received(data[partial:]) + server.protocol.data_received(data[:partial]) + server.protocol.data_received(data[partial:]) def test_data_received_multi_message_should_handle_messages(client_server): _, server = client_server messages = (dummy_message(i) for i in range(3)) data = b"".join(messages) - server.lsp.data_received(data) + server.protocol.data_received(data) def test_data_received_error_should_raise_jsonrpc_error(client_server): @@ -628,8 +628,8 @@ def test_data_received_error_should_raise_jsonrpc_error(client_server): body, ] ).encode("utf-8") - future = server.lsp._request_futures["err"] = Future() - server.lsp.data_received(message) + future = server.protocol._request_futures["err"] = Future() + server.protocol.data_received(message) with pytest.raises(JsonRpcException, match="message for you sir"): future.result() @@ -642,7 +642,7 @@ def test_initialize_should_return_server_capabilities(client_server): capabilities=ClientCapabilities(), ) - server_capabilities = server.lsp.lsp_initialize(params) + server_capabilities = server.protocol.lsp_initialize(params) assert isinstance(server_capabilities, InitializeResult) @@ -650,11 +650,11 @@ def test_initialize_should_return_server_capabilities(client_server): def test_ignore_unknown_notification(client_server): _, server = client_server - fn = server.lsp._execute_notification - server.lsp._execute_notification = Mock() + fn = server.protocol._execute_notification + server.protocol._execute_notification = Mock() - server.lsp._handle_notification("random/notification", None) - assert not server.lsp._execute_notification.called + server.protocol._handle_notification("random/notification", None) + assert not server.protocol._execute_notification.called # Remove mock - server.lsp._execute_notification = fn + server.protocol._execute_notification = fn diff --git a/tests/test_server_connection.py b/tests/test_server_connection.py index 1fda258b..c5aaaf56 100644 --- a/tests/test_server_connection.py +++ b/tests/test_server_connection.py @@ -7,7 +7,7 @@ import pytest from pygls import IS_PYODIDE -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer try: import websockets @@ -24,8 +24,8 @@ async def test_tcp_connection_lost(): server = LanguageServer("pygls-test", "v1", loop=loop) - server.lsp.connection_made = Mock() - server.lsp.connection_lost = Mock() + server.protocol.connection_made = Mock() + server.protocol.connection_lost = Mock() # Run the server over TCP in a separate thread server_thread = Thread( @@ -47,13 +47,13 @@ async def test_tcp_connection_lost(): reader, writer = await asyncio.open_connection("127.0.0.1", port) await asyncio.sleep(1) - assert server.lsp.connection_made.called + assert server.protocol.connection_made.called # Socket is closed (client's process is terminated) writer.close() await asyncio.sleep(1) - assert server.lsp.connection_lost.called + assert server.protocol.connection_lost.called @pytest.mark.asyncio @@ -65,7 +65,7 @@ async def test_io_connection_lost(): scr, scw = os.pipe() server = LanguageServer("pygls-test", "v1", loop=asyncio.new_event_loop()) - server.lsp.connection_made = Mock() + server.protocol.connection_made = Mock() server_thread = Thread( target=server.start_io, args=(os.fdopen(csr, "rb"), os.fdopen(scw, "wb")) ) @@ -73,7 +73,7 @@ async def test_io_connection_lost(): server_thread.start() # Wait for server to be ready - while not server.lsp.connection_made.called: + while not server.protocol.connection_made.called: await asyncio.sleep(0.5) # Pipe is closed (client's process is terminated) From ded4a0a8cb804e96bed568c04d0cd0c1d0e5369e Mon Sep 17 00:00:00 2001 From: Alex Carney Date: Tue, 20 Aug 2024 21:09:04 +0100 Subject: [PATCH 6/9] docs: add draft v2 migration guide --- docs/source/howto.rst | 1 + docs/source/howto/migrate-to-v2.rst | 351 ++++++++++++++++++++++++++++ docs/source/index.rst | 1 - docs/source/reference/servers.rst | 5 +- 4 files changed, 356 insertions(+), 2 deletions(-) create mode 100644 docs/source/howto/migrate-to-v2.rst diff --git a/docs/source/howto.rst b/docs/source/howto.rst index b2fb5f43..71d32960 100644 --- a/docs/source/howto.rst +++ b/docs/source/howto.rst @@ -7,4 +7,5 @@ How To Guides Handle Invalid Data Implement Semantic Tokens Migrate to v1 + Migrate to v2 Use the pygls-playground diff --git a/docs/source/howto/migrate-to-v2.rst b/docs/source/howto/migrate-to-v2.rst new file mode 100644 index 00000000..32e8acdb --- /dev/null +++ b/docs/source/howto/migrate-to-v2.rst @@ -0,0 +1,351 @@ +How To Migrate to v2.0 +====================== + +.. note:: + + This guide is still a draft, some details may change + +The highlight of the *pygls* v2 release is upgrading ``lsprotocol`` to ``v2024.x`` bringing with it support for the proposed LSP v3.18 types and methods. +It also includes standardised object names (so no more classes like ``NotebookDocumentSyncRegistrationOptionsNotebookSelectorType2CellsType``!) + +This guide outlines how to adapt an existing server to the breaking changes introduced in this release. + +**Known Migrations** + +You may find insight and inspiration from these projects that have already successfully migrated to v2: + +.. NOTE: The missing link below will be filled in a future PR once we have a stable hash for the commit that updates the example servers. + +- Our `example servers <>`__ + + +Renamed LanguageServer Methods +------------------------------ + +The :class:`~pygls.lsp.LanuageServer` class has been moved to the ``pygls.lsp`` module:: + + # Before + from pygls.server import LanguageServer + server = LanguageServer(name="my-language-server", version="v1.0") + + # After + from pygls.lsp.server import LanguageServer + server = LanguageServer(name="my-language-server", version="v1.0") + +All server-side LSP methods are now automatically generated from the specification, as a result the following methods have been renamed + +================================================== ============== +**pygls v1** **pygls v2** +================================================== ============== +``LanguageServer.apply_edit`` ``LanguageServer.workspace_apply_edit`` +``LanguageServer.apply_edit_async`` ``LanguageServer.workspace_apply_edit_async`` +``LanguageServer.get_configuration`` ``LanguageServer.workspace_configuration`` +``LanguageServer.get_configuration_async`` ``LanguageServer.workspace_configuration_async`` +``LanguageServer.publish_diagnostics`` ``LanguageServer.text_document_publish_diagnostics`` +``LanguageServer.register_capability`` ``LanguageServer.client_register_capability`` +``LanguageServer.register_capability_async`` ``LanguageServer.client_register_capability_async`` +``LanguageServer.semantic_tokens_refresh`` ``LanguageServer.workspace_semantic_tokens_refresh`` +``LanguageServer.semantic_tokens_refresh_async`` ``LanguageServer.workspace_semantic_tokens_refresh_async`` +``LanguageServer.show_document`` ``LanguageServer.window_show_document`` +``LanguageServer.show_document_async`` ``LanguageServer.window_show_document_async`` +``LanguageServer.show_message`` ``LanguageServer.window_show_message`` +``LanguageServer.show_message_log`` ``LanguageServer.window_log_message`` +``LanguageServer.unregister_capability`` ``LanguageServer.client_unregister_capability`` +``LanguageServer.unregister_capability_async`` ``LanguageServer.client_unregister_capability_async`` +================================================== ============== + +Additionally all LSP method signatures now require an instance of the corresponding ``params`` object for the method. +For example:: + + # Before + from pygls.server import LanguageServer + + server = LanguageServer(name="my-language-server", version="v1.0") + server.publish_diagnostics(uri='...', diagnostics=[...]) + + # After + from lsprotocol import types + from pygls.lsp.server import LanguageServer + + server = LanguageServer(name="my-language-server", version="v1.0") + server.text_document_publish_diagnostics( + types.PublishDiagnosticsParams( + uri='...', + diagnostics=[...], + ) + ) + +Renamed ``LanguageServer.progress`` +----------------------------------- + +A consequence of the automatic method generation ``LanguageServer.progress`` now sends a ``$/progress`` notification, rather than giving access to pygls' :class:`~pygls.progress.Progress` helper. + +The helper is now accessed via ``LanguageServer.work_done_progress`` + +**Before** + +:: + + from lsprotocol import types + from pygls.server import LanguageServer + + server = LanguageServer(name="my-language-server", version="v1.0") + + @server.command('progress.example') + async def progress(ls: LanguageServer, *args): + """Create and start the progress on the client.""" + token = str(uuid.uuid4()) + # Create + await ls.progress.create_async(token) + # Begin + ls.progress.begin( + token, + types.WorkDoneProgressBegin(title="Indexing", percentage=0, cancellable=True), + ) + # Report + for i in range(1, 10): + # Check for cancellation from client + if ls.progress.tokens[token].cancelled(): + # ... and stop the computation if client cancelled + return + ls.progress.report( + token, + types.WorkDoneProgressReport(message=f"{i * 10}%", percentage=i * 10), + ) + await asyncio.sleep(2) + # End + ls.progress.end(token, types.WorkDoneProgressEnd(message="Finished")) + + +**After** + +:: + + from lsprotocol import types + from pygls.lsp.server import LanguageServer + + server = LanguageServer(name="my-language-server", version="v1.0") + + @server.command('progress.example') + async def progress(ls: LanguageServer, *args): + """Create and start the progress on the client.""" + token = str(uuid.uuid4()) + # Create + await ls.work_done_progress.create_async(token) + # Begin + ls.work_done_progress.begin( + token, + types.WorkDoneProgressBegin(title="Indexing", percentage=0, cancellable=True), + ) + # Report + for i in range(1, 10): + # Check for cancellation from client + if ls.work_done_progress.tokens[token].cancelled(): + # ... and stop the computation if client cancelled + return + ls.work_done_progress.report( + token, + types.WorkDoneProgressReport(message=f"{i * 10}%", percentage=i * 10), + ) + await asyncio.sleep(2) + # End + ls.work_done_progress.end(token, types.WorkDoneProgressEnd(message="Finished")) + +Renamed LSP Types +----------------- + +As part of the update to ``lsprotocol v2024``, the following types have been renamed. + +=================================================================================== ============== +**lsprotocol 2023.x** **lsprotocol 2024.x** +=================================================================================== ============== +``CancelRequestNotification`` ``CancelNotification`` +``ClientRegisterCapabilityRequest`` ``RegistrationRequest`` +``ClientRegisterCapabilityResponse`` ``RegistrationResponse`` +``ClientUnregisterCapabilityRequest`` ``UnregistrationRequest`` +``ClientUnregisterCapabilityResponse`` ``UnregistrationResponse`` +``CodeActionClientCapabilitiesCodeActionLiteralSupportType`` ``ClientCodeActionLiteralOptions`` +``CodeActionClientCapabilitiesCodeActionLiteralSupportTypeCodeActionKindType`` ``ClientCodeActionKindOptions`` +``CodeActionClientCapabilitiesResolveSupportType`` ``ClientCodeActionResolveOptions`` +``CodeActionDisabledType`` ``CodeActionDisabled`` +``CompletionClientCapabilitiesCompletionItemKindType`` ``ClientCompletionItemOptionsKind`` +``CompletionClientCapabilitiesCompletionItemType`` ``ClientCompletionItemOptions`` +``CompletionClientCapabilitiesCompletionItemTypeInsertTextModeSupportType`` ``ClientCompletionItemInsertTextModeOptions`` +``CompletionClientCapabilitiesCompletionItemTypeResolveSupportType`` ``ClientSymbolResolveOptions`` +``CompletionClientCapabilitiesCompletionItemTypeTagSupportType`` ``CompletionItemTagOptions`` +``CompletionClientCapabilitiesCompletionListType`` ``CompletionListCapabilities`` +``CompletionItemResolveRequest`` ``CompletionResolveRequest`` +``CompletionItemResolveResponse`` ``CompletionResolveResponse`` +``CompletionListItemDefaultsType`` ``CompletionItemDefaults`` +``CompletionListItemDefaultsTypeEditRangeType1`` ``EditRangeWithInsertReplace`` +``CompletionOptionsCompletionItemType`` ``ServerCompletionItemOptions`` +``CompletionRegistrationOptionsCompletionItemType`` ``ServerCompletionItemOptions`` +``DocumentSymbolClientCapabilitiesSymbolKindType`` ``ClientSymbolKindOptions`` +``DocumentSymbolClientCapabilitiesTagSupportType`` ``ClientSymbolTagOptions`` +``FoldingRangeClientCapabilitiesFoldingRangeKindType`` ``ClientFoldingRangeKindOptions`` +``FoldingRangeClientCapabilitiesFoldingRangeType`` ``ClientFoldingRangeOptions`` +``GeneralClientCapabilitiesStaleRequestSupportType`` ``StaleRequestSupportOptions`` +``InitializeParamsClientInfoType`` ``ClientInfo`` +``InitializeResultServerInfoType`` ``ServerInfo`` +``InlayHintClientCapabilitiesResolveSupportType`` ``ClientInlayHintResolveOptions`` +``MarkedString_Type1`` ``MarkedStringWithLanguage`` +``NotebookDocumentChangeEventCellsType`` ``NotebookDocumentCellChanges`` +``NotebookDocumentChangeEventCellsTypeStructureType`` ``NotebookDocumentCellChangeStructure`` +``NotebookDocumentChangeEventCellsTypeTextContentType`` ``NotebookDocumentCellContentChanges`` +``NotebookDocumentDidChangeNotification`` ``DidChangeNotebookDocumentNotification`` +``NotebookDocumentDidCloseNotification`` ``DidCloseNotebookDocumentNotification`` +``NotebookDocumentDidOpenNotification`` ``DidOpenNotebookDocumentNotification`` +``NotebookDocumentDidSaveNotification`` ``DidSaveNotebookDocumentNotification`` +``NotebookDocumentFilter_Type1`` ``NotebookDocumentFilterNotebookType`` +``NotebookDocumentFilter_Type2`` ``NotebookDocumentFilterScheme`` +``NotebookDocumentFilter_Type3`` ``NotebookDocumentFilterPattern`` +``NotebookDocumentSyncOptionsNotebookSelectorType1`` ``NotebookDocumentFilterWithNotebook`` +``NotebookDocumentSyncOptionsNotebookSelectorType1CellsType`` ``NotebookCellLanguage`` +``NotebookDocumentSyncOptionsNotebookSelectorType2`` ``NotebookDocumentFilterWithCells`` +``NotebookDocumentSyncOptionsNotebookSelectorType2CellsType`` ``NotebookCellLanguage`` +``NotebookDocumentSyncRegistrationOptionsNotebookSelectorType1`` ``NotebookDocumentFilterWithNotebook`` +``NotebookDocumentSyncRegistrationOptionsNotebookSelectorType1CellsType`` ``NotebookCellLanguage`` +``NotebookDocumentSyncRegistrationOptionsNotebookSelectorType2`` ``NotebookDocumentFilterWithCells`` +``NotebookDocumentSyncRegistrationOptionsNotebookSelectorType2CellsType`` ``NotebookCellLanguage`` +``PrepareRenameResult_Type1`` ``PrepareRenamePlaceholder`` +``PrepareRenameResult_Type2`` ``PrepareRenameDefaultBehavior`` +``PublishDiagnosticsClientCapabilitiesTagSupportType`` ``ClientDiagnosticsTagOptions`` +``SemanticTokensClientCapabilitiesRequestsType`` ``ClientSemanticTokensRequestOptions`` +``SemanticTokensClientCapabilitiesRequestsTypeFullType1`` ``ClientSemanticTokensRequestFullDelta`` +``SemanticTokensOptionsFullType1`` ``SemanticTokensFullDelta`` +``SemanticTokensRegistrationOptionsFullType1`` ``SemanticTokensFullDelta`` +``ServerCapabilitiesWorkspaceType`` ``WorkspaceOptions`` +``ShowMessageRequestClientCapabilitiesMessageActionItemType`` ``ClientShowMessageActionItemOptions`` +``SignatureHelpClientCapabilitiesSignatureInformationType`` ``ClientSignatureInformationOptions`` +``SignatureHelpClientCapabilitiesSignatureInformationTypeParameterInformationType`` ``ClientSignatureParameterInformationOptions`` +``TextDocumentCodeActionRequest`` ``CodeActionRequest`` +``TextDocumentCodeActionResponse`` ``CodeActionResponse`` +``TextDocumentCodeLensRequest`` ``CodeLensRequest`` +``TextDocumentCodeLensResponse`` ``CodeLensResponse`` +``TextDocumentColorPresentationOptions`` ``ColorPresentationRequestOptions`` +``TextDocumentColorPresentationRequest`` ``ColorPresentationRequest`` +``TextDocumentColorPresentationResponse`` ``ColorPresentationResponse`` +``TextDocumentCompletionRequest`` ``CompletionRequest`` +``TextDocumentCompletionResponse`` ``CompletionResponse`` +``TextDocumentContentChangeEvent_Type1`` ``TextDocumentContentChangePartial`` +``TextDocumentContentChangeEvent_Type2`` ``TextDocumentContentChangeWholeDocument`` +``TextDocumentDeclarationRequest`` ``DeclarationRequest`` +``TextDocumentDeclarationResponse`` ``DeclarationResponse`` +``TextDocumentDefinitionRequest`` ``DefinitionRequest`` +``TextDocumentDefinitionResponse`` ``DefinitionResponse`` +``TextDocumentDiagnosticRequest`` ``DocumentDiagnosticRequest`` +``TextDocumentDiagnosticResponse`` ``DocumentDiagnosticResponse`` +``TextDocumentDidChangeNotification`` ``DidChangeTextDocumentNotification`` +``TextDocumentDidCloseNotification`` ``DidCloseTextDocumentNotification`` +``TextDocumentDidOpenNotification`` ``DidOpenTextDocumentNotification`` +``TextDocumentDidSaveNotification`` ``DidSaveTextDocumentNotification`` +``TextDocumentDocumentColorRequest`` ``DocumentColorRequest`` +``TextDocumentDocumentColorResponse`` ``DocumentColorResponse`` +``TextDocumentDocumentHighlightRequest`` ``DocumentHighlightRequest`` +``TextDocumentDocumentHighlightResponse`` ``DocumentHighlightResponse`` +``TextDocumentDocumentLinkRequest`` ``DocumentLinkRequest`` +``TextDocumentDocumentLinkResponse`` ``DocumentLinkResponse`` +``TextDocumentDocumentSymbolRequest`` ``DocumentSymbolRequest`` +``TextDocumentDocumentSymbolResponse`` ``DocumentSymbolResponse`` +``TextDocumentFilter_Type1`` ``TextDocumentFilterLanguage`` +``TextDocumentFilter_Type2`` ``TextDocumentFilterScheme`` +``TextDocumentFilter_Type3`` ``TextDocumentFilterPattern`` +``TextDocumentFoldingRangeRequest`` ``FoldingRangeRequest`` +``TextDocumentFoldingRangeResponse`` ``FoldingRangeResponse`` +``TextDocumentFormattingRequest`` ``DocumentFormattingRequest`` +``TextDocumentFormattingResponse`` ``DocumentFormattingResponse`` +``TextDocumentHoverRequest`` ``HoverRequest`` +``TextDocumentHoverResponse`` ``HoverResponse`` +``TextDocumentImplementationRequest`` ``ImplementationRequest`` +``TextDocumentImplementationResponse`` ``ImplementationResponse`` +``TextDocumentInlayHintRequest`` ``InlayHintRequest`` +``TextDocumentInlayHintResponse`` ``InlayHintResponse`` +``TextDocumentInlineCompletionRequest`` ``InlineCompletionRequest`` +``TextDocumentInlineCompletionResponse`` ``InlineCompletionResponse`` +``TextDocumentInlineValueRequest`` ``InlineValueRequest`` +``TextDocumentInlineValueResponse`` ``InlineValueResponse`` +``TextDocumentLinkedEditingRangeRequest`` ``LinkedEditingRangeRequest`` +``TextDocumentLinkedEditingRangeResponse`` ``LinkedEditingRangeResponse`` +``TextDocumentMonikerRequest`` ``MonikerRequest`` +``TextDocumentMonikerResponse`` ``MonikerResponse`` +``TextDocumentOnTypeFormattingRequest`` ``DocumentOnTypeFormattingRequest`` +``TextDocumentOnTypeFormattingResponse`` ``DocumentOnTypeFormattingResponse`` +``TextDocumentPrepareCallHierarchyRequest`` ``CallHierarchyPrepareRequest`` +``TextDocumentPrepareCallHierarchyResponse`` ``CallHierarchyPrepareResponse`` +``TextDocumentPrepareRenameRequest`` ``PrepareRenameRequest`` +``TextDocumentPrepareRenameResponse`` ``PrepareRenameResponse`` +``TextDocumentPrepareTypeHierarchyRequest`` ``TypeHierarchyPrepareRequest`` +``TextDocumentPrepareTypeHierarchyResponse`` ``TypeHierarchyPrepareResponse`` +``TextDocumentPublishDiagnosticsNotification`` ``PublishDiagnosticsNotification`` +``TextDocumentRangeFormattingRequest`` ``DocumentRangeFormattingRequest`` +``TextDocumentRangeFormattingResponse`` ``DocumentRangeFormattingResponse`` +``TextDocumentRangesFormattingRequest`` ``DocumentRangesFormattingRequest`` +``TextDocumentRangesFormattingResponse`` ``DocumentRangesFormattingResponse`` +``TextDocumentReferencesRequest`` ``ReferencesRequest`` +``TextDocumentReferencesResponse`` ``ReferencesResponse`` +``TextDocumentRenameRequest`` ``RenameRequest`` +``TextDocumentRenameResponse`` ``RenameResponse`` +``TextDocumentSelectionRangeRequest`` ``SelectionRangeRequest`` +``TextDocumentSelectionRangeResponse`` ``SelectionRangeResponse`` +``TextDocumentSemanticTokensFullDeltaRequest`` ``SemanticTokensDeltaRequest`` +``TextDocumentSemanticTokensFullDeltaResponse`` ``SemanticTokensDeltaResponse`` +``TextDocumentSemanticTokensFullRequest`` ``SemanticTokensRequest`` +``TextDocumentSemanticTokensFullResponse`` ``SemanticTokensResponse`` +``TextDocumentSemanticTokensRangeRequest`` ``SemanticTokensRangeRequest`` +``TextDocumentSemanticTokensRangeResponse`` ``SemanticTokensRangeResponse`` +``TextDocumentSignatureHelpRequest`` ``SignatureHelpRequest`` +``TextDocumentSignatureHelpResponse`` ``SignatureHelpResponse`` +``TextDocumentTypeDefinitionRequest`` ``TypeDefinitionRequest`` +``TextDocumentTypeDefinitionResponse`` ``TypeDefinitionResponse`` +``TextDocumentWillSaveNotification`` ``WillSaveTextDocumentNotification`` +``TextDocumentWillSaveWaitUntilRequest`` ``WillSaveTextDocumentWaitUntilRequest`` +``TextDocumentWillSaveWaitUntilResponse`` ``WillSaveTextDocumentWaitUntilResponse`` +``TraceValues`` ``TraceValue`` +``WindowLogMessageNotification`` ``LogMessageNotification`` +``WindowShowDocumentRequest`` ``ShowDocumentRequest`` +``WindowShowDocumentResponse`` ``ShowDocumentResponse`` +``WindowShowMessageNotification`` ``ShowMessageNotification`` +``WindowShowMessageRequestRequest`` ``ShowMessageRequest`` +``WindowShowMessageRequestResponse`` ``ShowMessageResponse`` +``WindowWorkDoneProgressCancelNotification`` ``WorkDoneProgressCancelNotification`` +``WindowWorkDoneProgressCreateRequest`` ``WorkDoneProgressCreateRequest`` +``WindowWorkDoneProgressCreateResponse`` ``WorkDoneProgressCreateResponse`` +``WorkspaceApplyEditRequest`` ``ApplyWorkspaceEditRequest`` +``WorkspaceApplyEditResponse`` ``ApplyWorkspaceEditResponse`` +``WorkspaceCodeLensRefreshRequest`` ``CodeLensRefreshRequest`` +``WorkspaceCodeLensRefreshResponse`` ``CodeLensRefreshResponse`` +``WorkspaceConfigurationParams`` ``ConfigurationParams`` +``WorkspaceConfigurationRequest`` ``ConfigurationRequest`` +``WorkspaceConfigurationResponse`` ``ConfigurationResponse`` +``WorkspaceDiagnosticRefreshRequest`` ``DiagnosticRefreshRequest`` +``WorkspaceDiagnosticRefreshResponse`` ``DiagnosticRefreshResponse`` +``WorkspaceDidChangeConfigurationNotification`` ``DidChangeConfigurationNotification`` +``WorkspaceDidChangeWatchedFilesNotification`` ``DidChangeWatchedFilesNotification`` +``WorkspaceDidChangeWorkspaceFoldersNotification`` ``DidChangeWorkspaceFoldersNotification`` +``WorkspaceDidCreateFilesNotification`` ``DidCreateFilesNotification`` +``WorkspaceDidDeleteFilesNotification`` ``DidDeleteFilesNotification`` +``WorkspaceDidRenameFilesNotification`` ``DidRenameFilesNotification`` +``WorkspaceEditClientCapabilitiesChangeAnnotationSupportType`` ``ChangeAnnotationsSupportOptions`` +``WorkspaceExecuteCommandRequest`` ``ExecuteCommandRequest`` +``WorkspaceExecuteCommandResponse`` ``ExecuteCommandResponse`` +``WorkspaceFoldingRangeRefreshRequest`` ``FoldingRangeRefreshRequest`` +``WorkspaceFoldingRangeRefreshResponse`` ``FoldingRangeRefreshResponse`` +``WorkspaceInlayHintRefreshRequest`` ``InlayHintRefreshRequest`` +``WorkspaceInlayHintRefreshResponse`` ``InlayHintRefreshResponse`` +``WorkspaceInlineValueRefreshRequest`` ``InlineValueRefreshRequest`` +``WorkspaceInlineValueRefreshResponse`` ``InlineValueRefreshResponse`` +``WorkspaceSemanticTokensRefreshRequest`` ``SemanticTokensRefreshRequest`` +``WorkspaceSemanticTokensRefreshResponse`` ``SemanticTokensRefreshResponse`` +``WorkspaceSymbolClientCapabilitiesResolveSupportType`` ``ClientSymbolResolveOptions`` +``WorkspaceSymbolClientCapabilitiesSymbolKindType`` ``ClientSymbolKindOptions`` +``WorkspaceSymbolClientCapabilitiesTagSupportType`` ``ClientSymbolTagOptions`` +``WorkspaceSymbolLocationType1`` ``LocationUriOnly`` +``WorkspaceWillCreateFilesRequest`` ``WillCreateFilesRequest`` +``WorkspaceWillCreateFilesResponse`` ``WillCreateFilesResponse`` +``WorkspaceWillDeleteFilesRequest`` ``WillDeleteFilesRequest`` +``WorkspaceWillDeleteFilesResponse`` ``WillDeleteFilesResponse`` +``WorkspaceWillRenameFilesRequest`` ``WillRenameFilesRequest`` +``WorkspaceWillRenameFilesResponse`` ``WillRenameFilesResponse`` +``WorkspaceWorkspaceFoldersRequest`` ``WorkspaceFoldersRequest`` +``WorkspaceWorkspaceFoldersResponse`` ``WorkspaceFoldersResponse`` +=================================================================================== ============== diff --git a/docs/source/index.rst b/docs/source/index.rst index e706215c..9560f6a5 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,4 +1,3 @@ - *pygls* ======= diff --git a/docs/source/reference/servers.rst b/docs/source/reference/servers.rst index 2a664ed0..2c4e7693 100644 --- a/docs/source/reference/servers.rst +++ b/docs/source/reference/servers.rst @@ -1,7 +1,10 @@ Servers ======= -.. autoclass:: pygls.server.LanguageServer +.. autoclass:: pygls.lsp.LanguageServer + :members: + +.. autoclass:: pygls.progress.Progress :members: .. autoclass:: pygls.server.Server From c5155c753c89deb582653b5c63cc554213e1f176 Mon Sep 17 00:00:00 2001 From: Alex Carney Date: Thu, 22 Aug 2024 20:14:14 +0100 Subject: [PATCH 7/9] chore: rename scripts to `generate_code` --- pygls/lsp/_base_client.py | 2 +- pygls/lsp/_base_server.py | 2 +- pyproject.toml | 6 +++--- ...ptodate.py => check_generated_code_is_uptodate.py} | 2 +- .../{generate_client_server.py => generate_code.py} | 11 ++++++----- 5 files changed, 12 insertions(+), 11 deletions(-) rename scripts/{check_client_is_uptodate.py => check_generated_code_is_uptodate.py} (89%) rename scripts/{generate_client_server.py => generate_code.py} (96%) diff --git a/pygls/lsp/_base_client.py b/pygls/lsp/_base_client.py index 5941bd05..e3f7648b 100644 --- a/pygls/lsp/_base_client.py +++ b/pygls/lsp/_base_client.py @@ -1,4 +1,4 @@ -# GENERATED FROM scripts/generate_client_server.py -- DO NOT EDIT +# GENERATED FROM scripts/generate_code.py -- DO NOT EDIT # flake8: noqa from concurrent.futures import Future from lsprotocol import types diff --git a/pygls/lsp/_base_server.py b/pygls/lsp/_base_server.py index e7061396..fc8f4f24 100644 --- a/pygls/lsp/_base_server.py +++ b/pygls/lsp/_base_server.py @@ -1,4 +1,4 @@ -# GENERATED FROM scripts/generate_client_server.py -- DO NOT EDIT +# GENERATED FROM scripts/generate_code.py -- DO NOT EDIT # flake8: noqa from cattrs import Converter from concurrent.futures import Future diff --git a/pyproject.toml b/pyproject.toml index 02be3f56..4cb365ad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,9 +56,9 @@ asyncio_mode = "auto" test-pyodide = "python tests/pyodide_testrunner/run.py" ruff = "ruff check ." mypy = "mypy -p pygls" -check_generated_client = "python scripts/check_client_is_uptodate.py" +check_generated_code = "python scripts/check_generated_code_is_uptodate.py" check_commit_style = "npx commitlint --from origin/main --to HEAD --verbose --config commitlintrc.yaml" -generate_client = "python scripts/generate_client_server.py pygls/lsp" +generate_code = "python scripts/generate_code.py pygls/lsp" generate_contributors_md = "python scripts/generate_contributors_md.py" black_check = "black --check ." poetry_lock_check = "poetry check" @@ -78,7 +78,7 @@ ignore_fail = "return_non_zero" sequence = [ "ruff", "mypy", - "check_generated_client", + "check_generated_code", "check_commit_style", "black_check", "poetry_lock_check" diff --git a/scripts/check_client_is_uptodate.py b/scripts/check_generated_code_is_uptodate.py similarity index 89% rename from scripts/check_client_is_uptodate.py rename to scripts/check_generated_code_is_uptodate.py index 0db2a033..63b7ef8d 100644 --- a/scripts/check_client_is_uptodate.py +++ b/scripts/check_generated_code_is_uptodate.py @@ -23,7 +23,7 @@ print( ( "🔴 Pygls client or server not up to date\n" - "1. Re-generate with: `poetry run poe generate_client`\n" + "1. Re-generate with: `poetry run poe generate_code`\n" "2. Commit" ) ) diff --git a/scripts/generate_client_server.py b/scripts/generate_code.py similarity index 96% rename from scripts/generate_client_server.py rename to scripts/generate_code.py index 82675a55..c7e84716 100644 --- a/scripts/generate_client_server.py +++ b/scripts/generate_code.py @@ -1,4 +1,5 @@ -"""Script to automatically generate a lanaguge client from `lsprotocol` type definitons""" +"""Script to automatically generate a lanaguge client and server from `lsprotocol` +type definitons.""" import argparse import inspect @@ -242,7 +243,7 @@ def generate_client() -> str: methods.append(textwrap.indent(method, " ")) code = [ - "# GENERATED FROM scripts/generate_client_server.py -- DO NOT EDIT", + "# GENERATED FROM scripts/generate_code.py -- DO NOT EDIT", "# flake8: noqa", write_imports(imports), "", @@ -275,7 +276,7 @@ def generate_server() -> str: ("cattrs", "Converter"), ("pygls.protocol", "LanguageServerProtocol"), ("pygls.protocol", "default_converter"), - ("pygls.server", "Server"), + ("pygls.server", "JsonRPCServer"), ("typing", "Callable"), ("typing", "Optional"), ("typing", "Type"), @@ -298,12 +299,12 @@ def generate_server() -> str: methods.append(textwrap.indent(method, " ")) code = [ - "# GENERATED FROM scripts/generate_client_server.py -- DO NOT EDIT", + "# GENERATED FROM scripts/generate_code.py -- DO NOT EDIT", "# flake8: noqa", write_imports(imports), "", "", - "class BaseLanguageServer(Server):", + "class BaseLanguageServer(JsonRPCServer):", "", " protocol: LanguageServerProtocol", "", From 75f781da768bd24e091ac5ce9f2fbc8e407e21b2 Mon Sep 17 00:00:00 2001 From: Alex Carney Date: Thu, 22 Aug 2024 20:14:43 +0100 Subject: [PATCH 8/9] refactor: rename `Server` to `JsonRPCServer` --- docs/source/howto/migrate-to-v2.rst | 15 +++++++++++++++ pygls/lsp/_base_server.py | 4 ++-- pygls/protocol/json_rpc.py | 4 ++-- pygls/server.py | 2 +- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/docs/source/howto/migrate-to-v2.rst b/docs/source/howto/migrate-to-v2.rst index 32e8acdb..3fde3e02 100644 --- a/docs/source/howto/migrate-to-v2.rst +++ b/docs/source/howto/migrate-to-v2.rst @@ -349,3 +349,18 @@ As part of the update to ``lsprotocol v2024``, the following types have been ren ``WorkspaceWorkspaceFoldersRequest`` ``WorkspaceFoldersRequest`` ``WorkspaceWorkspaceFoldersResponse`` ``WorkspaceFoldersResponse`` =================================================================================== ============== + +Low Level Changes +----------------- + +The following changes are unlikely to affect you directly, but have been included for completeness. + +``LanguageServer.lsp`` is now ``LanguageServer.protocol`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you need to access the underlying protocol object this is now via the ``protocol`` attribute. + +``pygls.server.Server`` is now ``pygls.server.JsonRPCServer`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +pygls' base server class has been renamed diff --git a/pygls/lsp/_base_server.py b/pygls/lsp/_base_server.py index fc8f4f24..af47abd6 100644 --- a/pygls/lsp/_base_server.py +++ b/pygls/lsp/_base_server.py @@ -5,7 +5,7 @@ from lsprotocol import types from pygls.protocol import LanguageServerProtocol from pygls.protocol import default_converter -from pygls.server import Server +from pygls.server import JsonRPCServer import typing from typing import Any from typing import Callable @@ -14,7 +14,7 @@ from typing import Type -class BaseLanguageServer(Server): +class BaseLanguageServer(JsonRPCServer): protocol: LanguageServerProtocol diff --git a/pygls/protocol/json_rpc.py b/pygls/protocol/json_rpc.py index fd80595b..988aa476 100644 --- a/pygls/protocol/json_rpc.py +++ b/pygls/protocol/json_rpc.py @@ -59,7 +59,7 @@ if TYPE_CHECKING: from cattrs import Converter - from pygls.server import Server, WebSocketTransportAdapter + from pygls.server import JsonRPCServer, WebSocketTransportAdapter logger = logging.getLogger(__name__) @@ -121,7 +121,7 @@ class JsonRPCProtocol(asyncio.Protocol): VERSION = "2.0" - def __init__(self, server: Server, converter: Converter): + def __init__(self, server: JsonRPCServer, converter: Converter): self._server = server self._converter = converter diff --git a/pygls/server.py b/pygls/server.py index 29aee81f..d82b8874 100644 --- a/pygls/server.py +++ b/pygls/server.py @@ -147,7 +147,7 @@ def write(self, data: Any) -> None: asyncio.ensure_future(self._ws.send(data)) -class Server: +class JsonRPCServer: """Base server class Parameters From f043d9ad2efa1f6d6cc15a299a99f6f0d5c77adb Mon Sep 17 00:00:00 2001 From: Alex Carney Date: Thu, 22 Aug 2024 20:15:10 +0100 Subject: [PATCH 9/9] chore: add call for testing to README --- README.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index ffc939f5..1dd479ef 100644 --- a/README.md +++ b/README.md @@ -4,29 +4,28 @@ _pygls_ (pronounced like "pie glass") is a pythonic generic implementation of the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/specification) for use as a foundation for writing your own [Language Servers](https://langserver.org/) in just a few lines of code. +> [!IMPORTANT] +> The next major version, *pygls v2* is ready for testing. +> We encourage all existing server authors to try the [migration guide](https://pygls.readthedocs.io/en/latest/howto/migrate-to-v2.html) and let us know how you get on! + ## Quickstart ```python from pygls.lsp.server import LanguageServer -from lsprotocol.types import ( - TEXT_DOCUMENT_COMPLETION, - CompletionItem, - CompletionList, - CompletionParams, -) +from lsprotocol import types server = LanguageServer("example-server", "v0.1") -@server.feature(TEXT_DOCUMENT_COMPLETION) -def completions(params: CompletionParams): +@server.feature(types.TEXT_DOCUMENT_COMPLETION) +def completions(params: types.CompletionParams): items = [] - document = server.workspace.get_document(params.text_document.uri) + document = server.workspace.get_text_document(params.text_document.uri) current_line = document.lines[params.position.line].strip() if current_line.endswith("hello."): items = [ - CompletionItem(label="world"), - CompletionItem(label="friend"), + types.CompletionItem(label="world"), + types.CompletionItem(label="friend"), ] - return CompletionList(is_incomplete=False, items=items) + return types.CompletionList(is_incomplete=False, items=items) server.start_io() ```