mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 06:03:58 +00:00
Allow inlay hint tooltips to trigger hovers
This commit is contained in:
parent
a2ec010185
commit
21f37a6d9e
5 changed files with 80 additions and 60 deletions
|
@ -48,7 +48,7 @@ pub enum ReborrowHints {
|
||||||
pub enum InlayKind {
|
pub enum InlayKind {
|
||||||
BindingModeHint,
|
BindingModeHint,
|
||||||
ChainingHint,
|
ChainingHint,
|
||||||
ClosingBraceHint(Option<TextSize>),
|
ClosingBraceHint,
|
||||||
ClosureReturnTypeHint,
|
ClosureReturnTypeHint,
|
||||||
GenericParamListHint,
|
GenericParamListHint,
|
||||||
ImplicitReborrowHint,
|
ImplicitReborrowHint,
|
||||||
|
@ -57,11 +57,19 @@ pub enum InlayKind {
|
||||||
TypeHint,
|
TypeHint,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: This should live somewhere more general
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum RangeOrOffset {
|
||||||
|
Range(TextRange),
|
||||||
|
Offset(TextSize),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InlayHint {
|
pub struct InlayHint {
|
||||||
pub range: TextRange,
|
pub range: TextRange,
|
||||||
pub kind: InlayKind,
|
pub kind: InlayKind,
|
||||||
pub label: String,
|
pub label: String,
|
||||||
|
pub hover_trigger: Option<RangeOrOffset>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Feature: Inlay Hints
|
// Feature: Inlay Hints
|
||||||
|
@ -253,8 +261,9 @@ fn closing_brace_hints(
|
||||||
|
|
||||||
acc.push(InlayHint {
|
acc.push(InlayHint {
|
||||||
range: closing_token.text_range(),
|
range: closing_token.text_range(),
|
||||||
kind: InlayKind::ClosingBraceHint(name_offset),
|
kind: InlayKind::ClosingBraceHint,
|
||||||
label,
|
label,
|
||||||
|
hover_trigger: name_offset.map(RangeOrOffset::Offset),
|
||||||
});
|
});
|
||||||
|
|
||||||
None
|
None
|
||||||
|
@ -273,6 +282,7 @@ fn lifetime_fn_hints(
|
||||||
range: t.text_range(),
|
range: t.text_range(),
|
||||||
kind: InlayKind::LifetimeHint,
|
kind: InlayKind::LifetimeHint,
|
||||||
label,
|
label,
|
||||||
|
hover_trigger: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let param_list = func.param_list()?;
|
let param_list = func.param_list()?;
|
||||||
|
@ -431,6 +441,7 @@ fn lifetime_fn_hints(
|
||||||
range: func.name()?.syntax().text_range(),
|
range: func.name()?.syntax().text_range(),
|
||||||
kind: InlayKind::GenericParamListHint,
|
kind: InlayKind::GenericParamListHint,
|
||||||
label: format!("<{}>", allocated_lifetimes.iter().format(", "),).into(),
|
label: format!("<{}>", allocated_lifetimes.iter().format(", "),).into(),
|
||||||
|
hover_trigger: None,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
Some(())
|
Some(())
|
||||||
|
@ -464,6 +475,7 @@ fn closure_ret_hints(
|
||||||
kind: InlayKind::ClosureReturnTypeHint,
|
kind: InlayKind::ClosureReturnTypeHint,
|
||||||
label: hint_iterator(sema, &famous_defs, config, &ty)
|
label: hint_iterator(sema, &famous_defs, config, &ty)
|
||||||
.unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string()),
|
.unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string()),
|
||||||
|
hover_trigger: None,
|
||||||
});
|
});
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
@ -490,6 +502,7 @@ fn reborrow_hints(
|
||||||
range: expr.syntax().text_range(),
|
range: expr.syntax().text_range(),
|
||||||
kind: InlayKind::ImplicitReborrowHint,
|
kind: InlayKind::ImplicitReborrowHint,
|
||||||
label: label.to_string(),
|
label: label.to_string(),
|
||||||
|
hover_trigger: None,
|
||||||
});
|
});
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
@ -548,6 +561,7 @@ fn chaining_hints(
|
||||||
label: hint_iterator(sema, &famous_defs, config, &ty).unwrap_or_else(|| {
|
label: hint_iterator(sema, &famous_defs, config, &ty).unwrap_or_else(|| {
|
||||||
ty.display_truncated(sema.db, config.max_length).to_string()
|
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,
|
range,
|
||||||
kind: InlayKind::ParameterHint,
|
kind: InlayKind::ParameterHint,
|
||||||
label: param_name.into(),
|
label: param_name.into(),
|
||||||
|
// FIXME: Show hover for parameter
|
||||||
|
hover_trigger: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
acc.extend(hints);
|
acc.extend(hints);
|
||||||
|
@ -613,7 +629,12 @@ fn binding_mode_hints(
|
||||||
(true, false) => "&",
|
(true, false) => "&",
|
||||||
_ => return,
|
_ => 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 {
|
match pat {
|
||||||
ast::Pat::IdentPat(pat) if pat.ref_token().is_none() && pat.mut_token().is_none() => {
|
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::Mut) => "ref mut",
|
||||||
hir::BindingMode::Ref(Mutability::Shared) => "ref",
|
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,
|
kind: InlayKind::TypeHint,
|
||||||
label,
|
label,
|
||||||
|
hover_trigger: pat.name().map(|it| it.syntax().text_range()).map(RangeOrOffset::Range),
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(())
|
Some(())
|
||||||
|
|
|
@ -80,7 +80,9 @@ pub use crate::{
|
||||||
folding_ranges::{Fold, FoldKind},
|
folding_ranges::{Fold, FoldKind},
|
||||||
highlight_related::{HighlightRelatedConfig, HighlightedRange},
|
highlight_related::{HighlightRelatedConfig, HighlightedRange},
|
||||||
hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult},
|
hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult},
|
||||||
inlay_hints::{InlayHint, InlayHintsConfig, InlayKind, LifetimeElisionHints, ReborrowHints},
|
inlay_hints::{
|
||||||
|
InlayHint, InlayHintsConfig, InlayKind, LifetimeElisionHints, RangeOrOffset, ReborrowHints,
|
||||||
|
},
|
||||||
join_lines::JoinLinesConfig,
|
join_lines::JoinLinesConfig,
|
||||||
markup::Markup,
|
markup::Markup,
|
||||||
moniker::{MonikerKind, MonikerResult, PackageInformation},
|
moniker::{MonikerKind, MonikerResult, PackageInformation},
|
||||||
|
|
|
@ -1360,46 +1360,34 @@ pub(crate) fn handle_inlay_hints_resolve(
|
||||||
mut hint: InlayHint,
|
mut hint: InlayHint,
|
||||||
) -> Result<InlayHint> {
|
) -> Result<InlayHint> {
|
||||||
let _p = profile::span("handle_inlay_hints_resolve");
|
let _p = profile::span("handle_inlay_hints_resolve");
|
||||||
let succ = (|| {
|
let data = match hint.data.take() {
|
||||||
let data = match hint.data.take() {
|
Some(it) => it,
|
||||||
Some(it) => it,
|
None => return Ok(hint),
|
||||||
None => return Ok(None),
|
};
|
||||||
};
|
|
||||||
|
|
||||||
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(
|
let file_range = from_proto::file_range(
|
||||||
&snap,
|
&snap,
|
||||||
resolve_data.position.text_document,
|
resolve_data.text_document,
|
||||||
Range::new(resolve_data.position.position, resolve_data.position.position),
|
match resolve_data.position {
|
||||||
)?;
|
PositionOrRange::Position(pos) => Range::new(pos, pos),
|
||||||
let info = match snap.analysis.hover(&snap.config.hover(), file_range)? {
|
PositionOrRange::Range(range) => range,
|
||||||
None => return Ok(None),
|
},
|
||||||
Some(info) => info,
|
)?;
|
||||||
};
|
let info = match snap.analysis.hover(&snap.config.hover(), file_range)? {
|
||||||
|
None => return Ok(hint),
|
||||||
|
Some(info) => info,
|
||||||
|
};
|
||||||
|
|
||||||
let markup_kind =
|
let markup_kind =
|
||||||
snap.config.hover().documentation.map_or(ide::HoverDocFormat::Markdown, |kind| 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(),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// FIXME: hover actions?
|
||||||
|
hint.tooltip = Some(lsp_types::InlayHintTooltip::MarkupContent(to_proto::markup_content(
|
||||||
|
info.info.markup,
|
||||||
|
markup_kind,
|
||||||
|
)));
|
||||||
Ok(hint)
|
Ok(hint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -520,7 +520,8 @@ pub struct CompletionResolveData {
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct InlayHintResolveData {
|
pub struct InlayHintResolveData {
|
||||||
pub position: lsp_types::TextDocumentPositionParams,
|
pub text_document: TextDocumentIdentifier,
|
||||||
|
pub position: PositionOrRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
|
|
@ -432,11 +432,11 @@ pub(crate) fn inlay_hint(
|
||||||
| InlayKind::ChainingHint
|
| InlayKind::ChainingHint
|
||||||
| InlayKind::GenericParamListHint
|
| InlayKind::GenericParamListHint
|
||||||
| InlayKind::LifetimeHint
|
| 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 {
|
padding_left: Some(match inlay_hint.kind {
|
||||||
InlayKind::TypeHint => !render_colons,
|
InlayKind::TypeHint => !render_colons,
|
||||||
InlayKind::ChainingHint | InlayKind::ClosingBraceHint(_) => true,
|
InlayKind::ChainingHint | InlayKind::ClosingBraceHint => true,
|
||||||
InlayKind::BindingModeHint
|
InlayKind::BindingModeHint
|
||||||
| InlayKind::ClosureReturnTypeHint
|
| InlayKind::ClosureReturnTypeHint
|
||||||
| InlayKind::GenericParamListHint
|
| InlayKind::GenericParamListHint
|
||||||
|
@ -450,7 +450,7 @@ pub(crate) fn inlay_hint(
|
||||||
| InlayKind::GenericParamListHint
|
| InlayKind::GenericParamListHint
|
||||||
| InlayKind::ImplicitReborrowHint
|
| InlayKind::ImplicitReborrowHint
|
||||||
| InlayKind::TypeHint
|
| InlayKind::TypeHint
|
||||||
| InlayKind::ClosingBraceHint(_) => false,
|
| InlayKind::ClosingBraceHint => false,
|
||||||
InlayKind::BindingModeHint => inlay_hint.label != "&",
|
InlayKind::BindingModeHint => inlay_hint.label != "&",
|
||||||
InlayKind::ParameterHint | InlayKind::LifetimeHint => true,
|
InlayKind::ParameterHint | InlayKind::LifetimeHint => true,
|
||||||
}),
|
}),
|
||||||
|
@ -458,7 +458,7 @@ pub(crate) fn inlay_hint(
|
||||||
InlayKind::ParameterHint if render_colons => format!("{}:", inlay_hint.label),
|
InlayKind::ParameterHint if render_colons => format!("{}:", inlay_hint.label),
|
||||||
InlayKind::TypeHint if render_colons => format!(": {}", inlay_hint.label),
|
InlayKind::TypeHint if render_colons => format!(": {}", inlay_hint.label),
|
||||||
InlayKind::ClosureReturnTypeHint => format!(" -> {}", inlay_hint.label),
|
InlayKind::ClosureReturnTypeHint => format!(" -> {}", inlay_hint.label),
|
||||||
_ => inlay_hint.label,
|
_ => inlay_hint.label.clone(),
|
||||||
}),
|
}),
|
||||||
kind: match inlay_hint.kind {
|
kind: match inlay_hint.kind {
|
||||||
InlayKind::ParameterHint => Some(lsp_types::InlayHintKind::PARAMETER),
|
InlayKind::ParameterHint => Some(lsp_types::InlayHintKind::PARAMETER),
|
||||||
|
@ -469,22 +469,24 @@ pub(crate) fn inlay_hint(
|
||||||
| InlayKind::GenericParamListHint
|
| InlayKind::GenericParamListHint
|
||||||
| InlayKind::LifetimeHint
|
| InlayKind::LifetimeHint
|
||||||
| InlayKind::ImplicitReborrowHint
|
| InlayKind::ImplicitReborrowHint
|
||||||
| InlayKind::ClosingBraceHint(_) => None,
|
| InlayKind::ClosingBraceHint => None,
|
||||||
},
|
},
|
||||||
text_edits: None,
|
text_edits: None,
|
||||||
tooltip: None,
|
tooltip: Some(lsp_types::InlayHintTooltip::String(inlay_hint.label)),
|
||||||
data: match inlay_hint.kind {
|
data: inlay_hint.hover_trigger.map(|range_or_offset| {
|
||||||
InlayKind::ClosingBraceHint(Some(offset)) => Some(
|
to_value(lsp_ext::InlayHintResolveData {
|
||||||
to_value(lsp_ext::InlayHintResolveData {
|
text_document: text_document.clone(),
|
||||||
position: lsp_types::TextDocumentPositionParams {
|
position: match range_or_offset {
|
||||||
text_document: text_document.clone(),
|
ide::RangeOrOffset::Offset(offset) => {
|
||||||
position: position(line_index, offset),
|
lsp_ext::PositionOrRange::Position(position(line_index, offset))
|
||||||
},
|
}
|
||||||
})
|
ide::RangeOrOffset::Range(text_range) => {
|
||||||
.unwrap(),
|
lsp_ext::PositionOrRange::Range(range(line_index, text_range))
|
||||||
),
|
}
|
||||||
_ => None,
|
},
|
||||||
},
|
})
|
||||||
|
.unwrap()
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue