From d806c9af9cdb850987230705ac9c350eb0037206 Mon Sep 17 00:00:00 2001 From: Ayoub Benali Date: Sun, 14 Nov 2021 21:50:47 +0100 Subject: [PATCH] Send range with textDocument/hover This is needed to handle https://github.com/scalameta/metals/pull/3060 It should be handle by LSP package once https://github.com/microsoft/language-server-protocol/issues/377 is resolved --- Default.sublime-keymap | 7 ++++++ st4/LspMetalsHoverRange.py | 48 ++++++++++++++++++++++++++++++++++++++ st4/__init__.py | 1 + 3 files changed, 56 insertions(+) create mode 100644 Default.sublime-keymap create mode 100644 st4/LspMetalsHoverRange.py diff --git a/Default.sublime-keymap b/Default.sublime-keymap new file mode 100644 index 0000000..a70a305 --- /dev/null +++ b/Default.sublime-keymap @@ -0,0 +1,7 @@ +[ + // Show Type annotation on code selection + // { + // "command": "lsp_metals_hover_range", + // "keys": ["UNBOUND"] + // } +] diff --git a/st4/LspMetalsHoverRange.py b/st4/LspMetalsHoverRange.py new file mode 100644 index 0000000..0992f41 --- /dev/null +++ b/st4/LspMetalsHoverRange.py @@ -0,0 +1,48 @@ +from LSP.plugin.core.registry import LspTextCommand +from LSP.plugin.core.typing import Union +from LSP.plugin.core.protocol import Request, Range, TextDocumentIdentifier, Error, Hover +from LSP.plugin.core.views import first_selection_region, text_document_identifier, region_to_range, FORMAT_MARKED_STRING, FORMAT_MARKUP_CONTENT, minihtml, update_lsp_popup, show_lsp_popup +import sublime + +HoverOrError = Union[Hover, Error] + +class LspMetalsHoverRangeCommand(LspTextCommand): + session_name = "metals" + + def run(self, edit: sublime.Edit) -> None: + session = self.session_by_name() + if not session: + return + view = self.view + region = first_selection_region(view) + begin = region.begin() + document_range = { + "textDocument": text_document_identifier(view), + "range": region_to_range(view, region).to_lsp() + } + + def on_response(response: HoverOrError): + if isinstance(response, Error): + sublime.status_message('Hover error: {}'.format(response)) + + if response: + content = (response.get('contents') or '') if isinstance(response, dict) else '' + formated = minihtml(self.view, content, allowed_formats=FORMAT_MARKED_STRING | FORMAT_MARKUP_CONTENT) + if self.view.is_popup_visible(): + update_lsp_popup(self.view, formated) + else: + show_lsp_popup( + self.view, + formated, + flags=sublime.HIDE_ON_MOUSE_MOVE_AWAY, + location=begin + ) + + def on_error(error: Error): + sublime.status_message('Hover error: {}'.format(error)) + + session.send_request( + Request("textDocument/hover", document_range, self.view), + on_response, + on_error + ) diff --git a/st4/__init__.py b/st4/__init__.py index a3ddc2e..7e65bd5 100644 --- a/st4/__init__.py +++ b/st4/__init__.py @@ -17,6 +17,7 @@ import mdpopups from functools import reduce from . LspMetalsFocus import LspMetalsFocusViewCommand, ActiveViewListener +from . LspMetalsHoverRange import LspMetalsHoverRangeCommand # TODO: Bring to public API from LSP.plugin.core.views import location_to_encoded_filename