diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 35601f2efc7..afa67f72bed 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -241,6 +241,13 @@ fn try_hover_for_lint(attr: &ast::Attr, token: &SyntaxToken) -> Option Option> { +} + fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option { fn to_action(nav_target: NavigationTarget) -> HoverAction { HoverAction::Implementation(FilePosition { diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 83173e1c6b8..b6b741a22ab 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -423,6 +423,15 @@ pub fn hover( self.with_db(|db| hover::hover(db, position, config)) } + /// Returns a short text displaying the type for the expression. + pub fn hover_range( + &self, + config: &HoverConfig, + range: FileRange, + ) -> Cancellable>> { + self.with_db(|db| hover::hover_range(db, range, config)) + } + /// Return URL(s) for the documentation of the symbol under the cursor. pub fn external_docs( &self, diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 52b557f1568..ede3103abfa 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -867,14 +867,29 @@ pub(crate) fn handle_signature_help( pub(crate) fn handle_hover( snap: GlobalStateSnapshot, - params: lsp_types::HoverParams, + params: lsp_ext::HoverParams, ) -> Result> { let _p = profile::span("handle_hover"); - let position = from_proto::file_position(&snap, params.text_document_position_params)?; - let info = match snap.analysis.hover(&snap.config.hover(), position)? { - None => return Ok(None), - Some(info) => info, + let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; + let range = from_proto::file_range(&snap, params.text_document, params.range)?; + + let info = if range.end - range.start == 1 { + // It's a hover over a position + match snap + .analysis + .hover(&snap.config.hover(), FilePosition { file_id, offset: range.start })? + { + None => return Ok(None), + Some(info) => info, + } + } else { + // It's a hover over a range + match snap.analysis.hover_range(&snap.config.hover(), range)? { + None => return Ok(None), + Some(info) => info, + } }; + let line_index = snap.file_line_index(position.file_id)?; let range = to_proto::range(&line_index, info.range); let hover = lsp_ext::Hover { diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs index f11ad396e70..f6abd95e1e6 100644 --- a/crates/rust-analyzer/src/lsp_ext.rs +++ b/crates/rust-analyzer/src/lsp_ext.rs @@ -376,11 +376,18 @@ pub struct SnippetTextEdit { pub enum HoverRequest {} impl Request for HoverRequest { - type Params = lsp_types::HoverParams; + type Params = HoverParams; type Result = Option; const METHOD: &'static str = "textDocument/hover"; } +#[derive(Deserialize, Serialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct HoverParams { + pub text_document: TextDocumentIdentifier, + pub range: Range, +} + #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] pub struct Hover { #[serde(flatten)]