diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 4684f92ae8d..e84338f0c82 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -48,7 +48,7 @@ pub enum ReborrowHints { pub enum InlayKind { BindingModeHint, ChainingHint, - ClosingBraceHint(Option), + ClosingBraceHint, ClosureReturnTypeHint, GenericParamListHint, ImplicitReborrowHint, @@ -57,11 +57,19 @@ pub enum InlayKind { TypeHint, } +// FIXME: This should live somewhere more general +#[derive(Debug)] +pub enum RangeOrOffset { + Range(TextRange), + Offset(TextSize), +} + #[derive(Debug)] pub struct InlayHint { pub range: TextRange, pub kind: InlayKind, pub label: String, + pub hover_trigger: Option, } // Feature: Inlay Hints @@ -253,8 +261,9 @@ fn closing_brace_hints( acc.push(InlayHint { range: closing_token.text_range(), - kind: InlayKind::ClosingBraceHint(name_offset), + kind: InlayKind::ClosingBraceHint, label, + hover_trigger: name_offset.map(RangeOrOffset::Offset), }); None @@ -273,6 +282,7 @@ fn lifetime_fn_hints( range: t.text_range(), kind: InlayKind::LifetimeHint, label, + hover_trigger: None, }; let param_list = func.param_list()?; @@ -431,6 +441,7 @@ fn lifetime_fn_hints( range: func.name()?.syntax().text_range(), kind: InlayKind::GenericParamListHint, label: format!("<{}>", allocated_lifetimes.iter().format(", "),).into(), + hover_trigger: None, }), } Some(()) @@ -464,6 +475,7 @@ fn closure_ret_hints( kind: InlayKind::ClosureReturnTypeHint, label: hint_iterator(sema, &famous_defs, config, &ty) .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string()), + hover_trigger: None, }); Some(()) } @@ -490,6 +502,7 @@ fn reborrow_hints( range: expr.syntax().text_range(), kind: InlayKind::ImplicitReborrowHint, label: label.to_string(), + hover_trigger: None, }); Some(()) } @@ -548,6 +561,7 @@ fn chaining_hints( label: hint_iterator(sema, &famous_defs, config, &ty).unwrap_or_else(|| { ty.display_truncated(sema.db, config.max_length).to_string() }), + hover_trigger: Some(RangeOrOffset::Range(expr.syntax().text_range())), }); } } @@ -588,6 +602,8 @@ fn param_name_hints( range, kind: InlayKind::ParameterHint, label: param_name.into(), + // FIXME: Show hover for parameter + hover_trigger: None, }); acc.extend(hints); @@ -613,7 +629,12 @@ fn binding_mode_hints( (true, false) => "&", _ => return, }; - acc.push(InlayHint { range, kind: InlayKind::BindingModeHint, label: r.to_string() }); + acc.push(InlayHint { + range, + kind: InlayKind::BindingModeHint, + label: r.to_string(), + hover_trigger: None, + }); }); match pat { ast::Pat::IdentPat(pat) if pat.ref_token().is_none() && pat.mut_token().is_none() => { @@ -623,7 +644,12 @@ fn binding_mode_hints( hir::BindingMode::Ref(Mutability::Mut) => "ref mut", hir::BindingMode::Ref(Mutability::Shared) => "ref", }; - acc.push(InlayHint { range, kind: InlayKind::BindingModeHint, label: bm.to_string() }); + acc.push(InlayHint { + range, + kind: InlayKind::BindingModeHint, + label: bm.to_string(), + hover_trigger: None, + }); } _ => (), } @@ -673,6 +699,7 @@ fn bind_pat_hints( }, kind: InlayKind::TypeHint, label, + hover_trigger: pat.name().map(|it| it.syntax().text_range()).map(RangeOrOffset::Range), }); Some(()) diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index e5160f99f34..071da8097c5 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -80,7 +80,9 @@ pub use crate::{ folding_ranges::{Fold, FoldKind}, highlight_related::{HighlightRelatedConfig, HighlightedRange}, hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult}, - inlay_hints::{InlayHint, InlayHintsConfig, InlayKind, LifetimeElisionHints, ReborrowHints}, + inlay_hints::{ + InlayHint, InlayHintsConfig, InlayKind, LifetimeElisionHints, RangeOrOffset, ReborrowHints, + }, join_lines::JoinLinesConfig, markup::Markup, moniker::{MonikerKind, MonikerResult, PackageInformation}, diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 95a6f4f1945..510b37bb6f6 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -1360,46 +1360,34 @@ pub(crate) fn handle_inlay_hints_resolve( mut hint: InlayHint, ) -> Result { let _p = profile::span("handle_inlay_hints_resolve"); - let succ = (|| { - let data = match hint.data.take() { - Some(it) => it, - None => return Ok(None), - }; + let data = match hint.data.take() { + Some(it) => it, + None => return Ok(hint), + }; - let resolve_data: lsp_ext::InlayHintResolveData = serde_json::from_value(data)?; + let resolve_data: lsp_ext::InlayHintResolveData = serde_json::from_value(data)?; - let file_range = from_proto::file_range( - &snap, - resolve_data.position.text_document, - Range::new(resolve_data.position.position, resolve_data.position.position), - )?; - let info = match snap.analysis.hover(&snap.config.hover(), file_range)? { - None => return Ok(None), - Some(info) => info, - }; + let file_range = from_proto::file_range( + &snap, + resolve_data.text_document, + match resolve_data.position { + PositionOrRange::Position(pos) => Range::new(pos, pos), + PositionOrRange::Range(range) => range, + }, + )?; + let info = match snap.analysis.hover(&snap.config.hover(), file_range)? { + None => return Ok(hint), + Some(info) => info, + }; - let markup_kind = - snap.config.hover().documentation.map_or(ide::HoverDocFormat::Markdown, |kind| kind); - - // FIXME: hover actions? - hint.tooltip = Some(lsp_types::InlayHintTooltip::MarkupContent(to_proto::markup_content( - info.info.markup, - markup_kind, - ))); - Result::<_, crate::Error>::Ok(Some(())) - })()? - .is_some(); - - if !succ { - if let lsp_types::InlayHintLabel::String(s) = &hint.label { - hint.tooltip = - Some(lsp_types::InlayHintTooltip::MarkupContent(lsp_types::MarkupContent { - kind: lsp_types::MarkupKind::PlainText, - value: s.clone(), - })); - } - } + let markup_kind = + snap.config.hover().documentation.map_or(ide::HoverDocFormat::Markdown, |kind| kind); + // FIXME: hover actions? + hint.tooltip = Some(lsp_types::InlayHintTooltip::MarkupContent(to_proto::markup_content( + info.info.markup, + markup_kind, + ))); Ok(hint) } diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs index 8e7e2e23642..c1b230bd9df 100644 --- a/crates/rust-analyzer/src/lsp_ext.rs +++ b/crates/rust-analyzer/src/lsp_ext.rs @@ -520,7 +520,8 @@ pub struct CompletionResolveData { #[derive(Debug, Serialize, Deserialize)] pub struct InlayHintResolveData { - pub position: lsp_types::TextDocumentPositionParams, + pub text_document: TextDocumentIdentifier, + pub position: PositionOrRange, } #[derive(Debug, Serialize, Deserialize)] diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 9287d7c53e3..6817090a8bc 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -432,11 +432,11 @@ pub(crate) fn inlay_hint( | InlayKind::ChainingHint | InlayKind::GenericParamListHint | InlayKind::LifetimeHint - | InlayKind::ClosingBraceHint(_) => position(line_index, inlay_hint.range.end()), + | InlayKind::ClosingBraceHint => position(line_index, inlay_hint.range.end()), }, padding_left: Some(match inlay_hint.kind { InlayKind::TypeHint => !render_colons, - InlayKind::ChainingHint | InlayKind::ClosingBraceHint(_) => true, + InlayKind::ChainingHint | InlayKind::ClosingBraceHint => true, InlayKind::BindingModeHint | InlayKind::ClosureReturnTypeHint | InlayKind::GenericParamListHint @@ -450,7 +450,7 @@ pub(crate) fn inlay_hint( | InlayKind::GenericParamListHint | InlayKind::ImplicitReborrowHint | InlayKind::TypeHint - | InlayKind::ClosingBraceHint(_) => false, + | InlayKind::ClosingBraceHint => false, InlayKind::BindingModeHint => inlay_hint.label != "&", InlayKind::ParameterHint | InlayKind::LifetimeHint => true, }), @@ -458,7 +458,7 @@ pub(crate) fn inlay_hint( InlayKind::ParameterHint if render_colons => format!("{}:", inlay_hint.label), InlayKind::TypeHint if render_colons => format!(": {}", inlay_hint.label), InlayKind::ClosureReturnTypeHint => format!(" -> {}", inlay_hint.label), - _ => inlay_hint.label, + _ => inlay_hint.label.clone(), }), kind: match inlay_hint.kind { InlayKind::ParameterHint => Some(lsp_types::InlayHintKind::PARAMETER), @@ -469,22 +469,24 @@ pub(crate) fn inlay_hint( | InlayKind::GenericParamListHint | InlayKind::LifetimeHint | InlayKind::ImplicitReborrowHint - | InlayKind::ClosingBraceHint(_) => None, + | InlayKind::ClosingBraceHint => None, }, text_edits: None, - tooltip: None, - data: match inlay_hint.kind { - InlayKind::ClosingBraceHint(Some(offset)) => Some( - to_value(lsp_ext::InlayHintResolveData { - position: lsp_types::TextDocumentPositionParams { - text_document: text_document.clone(), - position: position(line_index, offset), - }, - }) - .unwrap(), - ), - _ => None, - }, + tooltip: Some(lsp_types::InlayHintTooltip::String(inlay_hint.label)), + data: inlay_hint.hover_trigger.map(|range_or_offset| { + to_value(lsp_ext::InlayHintResolveData { + text_document: text_document.clone(), + position: match range_or_offset { + ide::RangeOrOffset::Offset(offset) => { + lsp_ext::PositionOrRange::Position(position(line_index, offset)) + } + ide::RangeOrOffset::Range(text_range) => { + lsp_ext::PositionOrRange::Range(range(line_index, text_range)) + } + }, + }) + .unwrap() + }), } }