]> git.lizzy.rs Git - rust.git/commitdiff
feat: Add the hover_range capability
authorAlexander Gonzalez <alexfertel97@gmail.com>
Sun, 25 Jul 2021 01:54:48 +0000 (21:54 -0400)
committerAlexander Gonzalez <alexfertel97@gmail.com>
Tue, 27 Jul 2021 22:29:22 +0000 (18:29 -0400)
crates/ide/src/hover.rs
crates/rust-analyzer/src/handlers.rs

index afa67f72bed6b8d85610b0ea87aea2d758615b59..692c3ff676a804ec23bdba2d89e26fbc329873bb 100644 (file)
@@ -1,7 +1,7 @@
 use either::Either;
 use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, Semantics};
 use ide_db::{
-    base_db::SourceDatabase,
+    base_db::{FileRange, SourceDatabase},
     defs::{Definition, NameClass, NameRefClass},
     helpers::{
         generated_lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES},
 use itertools::Itertools;
 use stdx::format_to;
 use syntax::{
-    algo, ast, display::fn_as_proc_macro_label, match_ast, AstNode, AstToken, Direction,
-    SyntaxKind::*, SyntaxToken, T,
+    algo::{self, find_node_at_range},
+    ast,
+    display::fn_as_proc_macro_label,
+    match_ast, AstNode, AstToken, Direction,
+    SyntaxKind::*,
+    SyntaxToken, T,
 };
 
 use crate::{
@@ -246,6 +250,24 @@ pub(crate) fn hover_range(
     range: FileRange,
     config: &HoverConfig,
 ) -> Option<RangeInfo<HoverResult>> {
+    let sema = hir::Semantics::new(db);
+    let file = sema.parse(range.file_id).syntax().clone();
+    let expr = find_node_at_range::<ast::Expr>(&file, range.range)?;
+    let ty = sema.type_of_expr(&expr)?;
+
+    if ty.is_unknown() {
+        return None;
+    }
+
+    let mut res = HoverResult::default();
+
+    res.markup = if config.markdown() {
+        Markup::fenced_block(&ty.display(db))
+    } else {
+        ty.display(db).to_string().into()
+    };
+
+    Some(RangeInfo::new(range.range, res))
 }
 
 fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> {
index ede3103abfa00aa83559613484e942bd6b1ae446..6fae4b04a40d47e79a7987f40b5e63a324859bed 100644 (file)
@@ -873,24 +873,25 @@ pub(crate) fn handle_hover(
     let file_id = from_proto::file_id(&snap, &params.text_document.uri)?;
     let range = from_proto::file_range(&snap, params.text_document, params.range)?;
 
-    let info = if range.end - range.start == 1 {
+    let info = if range.range.is_empty() {
         // It's a hover over a position
         match snap
             .analysis
-            .hover(&snap.config.hover(), FilePosition { file_id, offset: range.start })?
+            .hover(&snap.config.hover(), FilePosition { file_id, offset: range.range.start() })?
         {
             None => return Ok(None),
             Some(info) => info,
         }
     } else {
         // It's a hover over a range
+        log::info!("Triggered range hover");
         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 line_index = snap.file_line_index(range.file_id)?;
     let range = to_proto::range(&line_index, info.range);
     let hover = lsp_ext::Hover {
         hover: lsp_types::Hover {