diff --git a/plugin/core/protocol.py b/plugin/core/protocol.py index 7df2d7e4b..7ef381fc9 100644 --- a/plugin/core/protocol.py +++ b/plugin/core/protocol.py @@ -72,6 +72,12 @@ class InsertTextMode: 'position': Position, }, total=True) +ExperimentalTextDocumentRangeParams = TypedDict('ExperimentalTextDocumentRangeParams', { + 'textDocument': TextDocumentIdentifier, + 'position': Position, + 'range': RangeLsp, +}, total=True) + CodeDescription = TypedDict('CodeDescription', { 'href': str }, total=True) diff --git a/plugin/core/views.py b/plugin/core/views.py index 9b1a471a8..8edcae6e1 100644 --- a/plugin/core/views.py +++ b/plugin/core/views.py @@ -5,6 +5,7 @@ from .protocol import DiagnosticRelatedInformation from .protocol import DiagnosticSeverity from .protocol import DocumentUri +from .protocol import ExperimentalTextDocumentRangeParams from .protocol import Location from .protocol import LocationLink from .protocol import MarkedString @@ -271,6 +272,15 @@ def text_document_position_params(view: sublime.View, location: int) -> TextDocu return {"textDocument": text_document_identifier(view), "position": position(view, location)} +def text_document_range_params(view: sublime.View, location: int, + region: sublime.Region) -> ExperimentalTextDocumentRangeParams: + return { + "textDocument": text_document_identifier(view), + "position": position(view, location), + "range": region_to_range(view, region).to_lsp() + } + + def did_open_text_document_params(view: sublime.View, language_id: str) -> Dict[str, Any]: return {"textDocument": text_document_item(view, language_id)} diff --git a/plugin/hover.py b/plugin/hover.py index aecbd2557..40ae7337f 100644 --- a/plugin/hover.py +++ b/plugin/hover.py @@ -4,12 +4,15 @@ from .core.promise import Promise from .core.protocol import Diagnostic from .core.protocol import Error +from .core.protocol import ExperimentalTextDocumentRangeParams from .core.protocol import Hover from .core.protocol import Position from .core.protocol import RangeLsp from .core.protocol import Request +from .core.protocol import TextDocumentPositionParams from .core.registry import LspTextCommand from .core.registry import windows +from .core.sessions import Session from .core.sessions import SessionBufferProtocol from .core.settings import userprefs from .core.typing import List, Optional, Dict, Tuple, Sequence, Union @@ -22,6 +25,7 @@ from .core.views import make_link from .core.views import show_lsp_popup from .core.views import text_document_position_params +from .core.views import text_document_range_params from .core.views import unpack_href_location from .core.views import update_lsp_popup from .core.windows import AbstractViewListener @@ -120,14 +124,23 @@ def run_async() -> None: def request_symbol_hover_async(self, listener: AbstractViewListener, point: int) -> None: hover_promises = [] # type: List[Promise[ResolvedHover]] - document_position = text_document_position_params(self.view, point) for session in listener.sessions_async('hoverProvider'): + document_position = self._create_hover_request(session, point) hover_promises.append(session.send_request_task( Request("textDocument/hover", document_position, self.view) )) Promise.all(hover_promises).then(lambda responses: self._on_all_settled(responses, listener, point)) + def _create_hover_request( + self, session: Session, point: int + ) -> Union[TextDocumentPositionParams, ExperimentalTextDocumentRangeParams]: + if session.get_capability('experimental.rangeHoverProvider'): + region = first_selection_region(self.view) + if region is not None and region.contains(point): + return text_document_range_params(self.view, point, region) + return text_document_position_params(self.view, point) + def _on_all_settled(self, responses: List[ResolvedHover], listener: AbstractViewListener, point: int) -> None: hovers = [] # type: List[Hover] errors = [] # type: List[Error]