Skip to content

Commit

Permalink
Allow plugins to modify server response messages (#1992)
Browse files Browse the repository at this point in the history
  • Loading branch information
jwortmann authored Jul 13, 2022
1 parent e7ca542 commit 9fa725a
Showing 1 changed file with 24 additions and 7 deletions.
31 changes: 24 additions & 7 deletions plugin/core/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,17 @@ def on_pre_send_notification_async(self, notification: Notification) -> None:
"""
pass

def on_server_response_async(self, method: str, response: Response) -> None:
"""
Notifies about a response message that has been received from the language server.
Only successful responses are passed to this method.
:param method: The method of the request.
:param response: The response object to the request. The response.result field can be modified by the
plugin, before it gets further handled by the LSP package.
"""
pass

def on_open_uri_async(self, uri: DocumentUri, callback: Callable[[str, str, str], None]) -> bool:
"""
Called when a language server reports to open an URI. If you know how to handle this URI, then return True and
Expand Down Expand Up @@ -1898,10 +1909,12 @@ def deduce_payload(
return res
elif "id" in payload:
response_id = int(payload["id"])
handler, result, is_error = self.response_handler(response_id, payload)
response_tuple = (handler, result, None, None, None)
handler, method, result, is_error = self.response_handler(response_id, payload)
self._logger.incoming_response(response_id, result, is_error)
return response_tuple
response = Response(response_id, result)
if self._plugin and not is_error:
self._plugin.on_server_response_async(method, response) # type: ignore
return handler, response.result, None, None, None
else:
debug("Unknown payload type: ", payload)
return (None, None, None, None, None)
Expand All @@ -1925,21 +1938,25 @@ def on_payload(self, payload: Dict[str, Any]) -> None:
except Exception as err:
exception_log("Error handling {}".format(typestr), err)

def response_handler(self, response_id: int, response: Dict[str, Any]) -> Tuple[Optional[Callable], Any, bool]:
def response_handler(
self,
response_id: int,
response: Dict[str, Any]
) -> Tuple[Optional[Callable], Optional[str], Any, bool]:
request, handler, error_handler = self._response_handlers.pop(response_id, (None, None, None))
if not request:
error = {"code": ErrorCode.InvalidParams, "message": "unknown response ID {}".format(response_id)}
return (print_to_status_bar, error, True)
return (print_to_status_bar, None, error, True)
self._invoke_views(request, "on_request_finished_async", response_id)
if "result" in response and "error" not in response:
return (handler, response["result"], False)
return (handler, request.method, response["result"], False)
if not error_handler:
error_handler = print_to_status_bar
if "result" not in response and "error" in response:
error = response["error"]
else:
error = {"code": ErrorCode.InvalidParams, "message": "invalid response payload"}
return (error_handler, error, True)
return (error_handler, request.method, error, True)

def _get_handler(self, method: str) -> Optional[Callable]:
return getattr(self, method2attr(method), None)

0 comments on commit 9fa725a

Please sign in to comment.