Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 21f37a6

Browse files
committed
Allow inlay hint tooltips to trigger hovers
1 parent a2ec010 commit 21f37a6

File tree

5 files changed

+80
-60
lines changed

5 files changed

+80
-60
lines changed

crates/ide/src/inlay_hints.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub enum ReborrowHints {
4848
pub enum InlayKind {
4949
BindingModeHint,
5050
ChainingHint,
51-
ClosingBraceHint(Option<TextSize>),
51+
ClosingBraceHint,
5252
ClosureReturnTypeHint,
5353
GenericParamListHint,
5454
ImplicitReborrowHint,
@@ -57,11 +57,19 @@ pub enum InlayKind {
5757
TypeHint,
5858
}
5959

60+
// FIXME: This should live somewhere more general
61+
#[derive(Debug)]
62+
pub enum RangeOrOffset {
63+
Range(TextRange),
64+
Offset(TextSize),
65+
}
66+
6067
#[derive(Debug)]
6168
pub struct InlayHint {
6269
pub range: TextRange,
6370
pub kind: InlayKind,
6471
pub label: String,
72+
pub hover_trigger: Option<RangeOrOffset>,
6573
}
6674

6775
// Feature: Inlay Hints
@@ -253,8 +261,9 @@ fn closing_brace_hints(
253261

254262
acc.push(InlayHint {
255263
range: closing_token.text_range(),
256-
kind: InlayKind::ClosingBraceHint(name_offset),
264+
kind: InlayKind::ClosingBraceHint,
257265
label,
266+
hover_trigger: name_offset.map(RangeOrOffset::Offset),
258267
});
259268

260269
None
@@ -273,6 +282,7 @@ fn lifetime_fn_hints(
273282
range: t.text_range(),
274283
kind: InlayKind::LifetimeHint,
275284
label,
285+
hover_trigger: None,
276286
};
277287

278288
let param_list = func.param_list()?;
@@ -431,6 +441,7 @@ fn lifetime_fn_hints(
431441
range: func.name()?.syntax().text_range(),
432442
kind: InlayKind::GenericParamListHint,
433443
label: format!("<{}>", allocated_lifetimes.iter().format(", "),).into(),
444+
hover_trigger: None,
434445
}),
435446
}
436447
Some(())
@@ -464,6 +475,7 @@ fn closure_ret_hints(
464475
kind: InlayKind::ClosureReturnTypeHint,
465476
label: hint_iterator(sema, &famous_defs, config, &ty)
466477
.unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string()),
478+
hover_trigger: None,
467479
});
468480
Some(())
469481
}
@@ -490,6 +502,7 @@ fn reborrow_hints(
490502
range: expr.syntax().text_range(),
491503
kind: InlayKind::ImplicitReborrowHint,
492504
label: label.to_string(),
505+
hover_trigger: None,
493506
});
494507
Some(())
495508
}
@@ -548,6 +561,7 @@ fn chaining_hints(
548561
label: hint_iterator(sema, &famous_defs, config, &ty).unwrap_or_else(|| {
549562
ty.display_truncated(sema.db, config.max_length).to_string()
550563
}),
564+
hover_trigger: Some(RangeOrOffset::Range(expr.syntax().text_range())),
551565
});
552566
}
553567
}
@@ -588,6 +602,8 @@ fn param_name_hints(
588602
range,
589603
kind: InlayKind::ParameterHint,
590604
label: param_name.into(),
605+
// FIXME: Show hover for parameter
606+
hover_trigger: None,
591607
});
592608

593609
acc.extend(hints);
@@ -613,7 +629,12 @@ fn binding_mode_hints(
613629
(true, false) => "&",
614630
_ => return,
615631
};
616-
acc.push(InlayHint { range, kind: InlayKind::BindingModeHint, label: r.to_string() });
632+
acc.push(InlayHint {
633+
range,
634+
kind: InlayKind::BindingModeHint,
635+
label: r.to_string(),
636+
hover_trigger: None,
637+
});
617638
});
618639
match pat {
619640
ast::Pat::IdentPat(pat) if pat.ref_token().is_none() && pat.mut_token().is_none() => {
@@ -623,7 +644,12 @@ fn binding_mode_hints(
623644
hir::BindingMode::Ref(Mutability::Mut) => "ref mut",
624645
hir::BindingMode::Ref(Mutability::Shared) => "ref",
625646
};
626-
acc.push(InlayHint { range, kind: InlayKind::BindingModeHint, label: bm.to_string() });
647+
acc.push(InlayHint {
648+
range,
649+
kind: InlayKind::BindingModeHint,
650+
label: bm.to_string(),
651+
hover_trigger: None,
652+
});
627653
}
628654
_ => (),
629655
}
@@ -673,6 +699,7 @@ fn bind_pat_hints(
673699
},
674700
kind: InlayKind::TypeHint,
675701
label,
702+
hover_trigger: pat.name().map(|it| it.syntax().text_range()).map(RangeOrOffset::Range),
676703
});
677704

678705
Some(())

crates/ide/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ pub use crate::{
8080
folding_ranges::{Fold, FoldKind},
8181
highlight_related::{HighlightRelatedConfig, HighlightedRange},
8282
hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult},
83-
inlay_hints::{InlayHint, InlayHintsConfig, InlayKind, LifetimeElisionHints, ReborrowHints},
83+
inlay_hints::{
84+
InlayHint, InlayHintsConfig, InlayKind, LifetimeElisionHints, RangeOrOffset, ReborrowHints,
85+
},
8486
join_lines::JoinLinesConfig,
8587
markup::Markup,
8688
moniker::{MonikerKind, MonikerResult, PackageInformation},

crates/rust-analyzer/src/handlers.rs

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,46 +1360,34 @@ pub(crate) fn handle_inlay_hints_resolve(
13601360
mut hint: InlayHint,
13611361
) -> Result<InlayHint> {
13621362
let _p = profile::span("handle_inlay_hints_resolve");
1363-
let succ = (|| {
1364-
let data = match hint.data.take() {
1365-
Some(it) => it,
1366-
None => return Ok(None),
1367-
};
1363+
let data = match hint.data.take() {
1364+
Some(it) => it,
1365+
None => return Ok(hint),
1366+
};
13681367

1369-
let resolve_data: lsp_ext::InlayHintResolveData = serde_json::from_value(data)?;
1368+
let resolve_data: lsp_ext::InlayHintResolveData = serde_json::from_value(data)?;
13701369

1371-
let file_range = from_proto::file_range(
1372-
&snap,
1373-
resolve_data.position.text_document,
1374-
Range::new(resolve_data.position.position, resolve_data.position.position),
1375-
)?;
1376-
let info = match snap.analysis.hover(&snap.config.hover(), file_range)? {
1377-
None => return Ok(None),
1378-
Some(info) => info,
1379-
};
1370+
let file_range = from_proto::file_range(
1371+
&snap,
1372+
resolve_data.text_document,
1373+
match resolve_data.position {
1374+
PositionOrRange::Position(pos) => Range::new(pos, pos),
1375+
PositionOrRange::Range(range) => range,
1376+
},
1377+
)?;
1378+
let info = match snap.analysis.hover(&snap.config.hover(), file_range)? {
1379+
None => return Ok(hint),
1380+
Some(info) => info,
1381+
};
13801382

1381-
let markup_kind =
1382-
snap.config.hover().documentation.map_or(ide::HoverDocFormat::Markdown, |kind| kind);
1383-
1384-
// FIXME: hover actions?
1385-
hint.tooltip = Some(lsp_types::InlayHintTooltip::MarkupContent(to_proto::markup_content(
1386-
info.info.markup,
1387-
markup_kind,
1388-
)));
1389-
Result::<_, crate::Error>::Ok(Some(()))
1390-
})()?
1391-
.is_some();
1392-
1393-
if !succ {
1394-
if let lsp_types::InlayHintLabel::String(s) = &hint.label {
1395-
hint.tooltip =
1396-
Some(lsp_types::InlayHintTooltip::MarkupContent(lsp_types::MarkupContent {
1397-
kind: lsp_types::MarkupKind::PlainText,
1398-
value: s.clone(),
1399-
}));
1400-
}
1401-
}
1383+
let markup_kind =
1384+
snap.config.hover().documentation.map_or(ide::HoverDocFormat::Markdown, |kind| kind);
14021385

1386+
// FIXME: hover actions?
1387+
hint.tooltip = Some(lsp_types::InlayHintTooltip::MarkupContent(to_proto::markup_content(
1388+
info.info.markup,
1389+
markup_kind,
1390+
)));
14031391
Ok(hint)
14041392
}
14051393

crates/rust-analyzer/src/lsp_ext.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,8 @@ pub struct CompletionResolveData {
520520

521521
#[derive(Debug, Serialize, Deserialize)]
522522
pub struct InlayHintResolveData {
523-
pub position: lsp_types::TextDocumentPositionParams,
523+
pub text_document: TextDocumentIdentifier,
524+
pub position: PositionOrRange,
524525
}
525526

526527
#[derive(Debug, Serialize, Deserialize)]

crates/rust-analyzer/src/to_proto.rs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -432,11 +432,11 @@ pub(crate) fn inlay_hint(
432432
| InlayKind::ChainingHint
433433
| InlayKind::GenericParamListHint
434434
| InlayKind::LifetimeHint
435-
| InlayKind::ClosingBraceHint(_) => position(line_index, inlay_hint.range.end()),
435+
| InlayKind::ClosingBraceHint => position(line_index, inlay_hint.range.end()),
436436
},
437437
padding_left: Some(match inlay_hint.kind {
438438
InlayKind::TypeHint => !render_colons,
439-
InlayKind::ChainingHint | InlayKind::ClosingBraceHint(_) => true,
439+
InlayKind::ChainingHint | InlayKind::ClosingBraceHint => true,
440440
InlayKind::BindingModeHint
441441
| InlayKind::ClosureReturnTypeHint
442442
| InlayKind::GenericParamListHint
@@ -450,15 +450,15 @@ pub(crate) fn inlay_hint(
450450
| InlayKind::GenericParamListHint
451451
| InlayKind::ImplicitReborrowHint
452452
| InlayKind::TypeHint
453-
| InlayKind::ClosingBraceHint(_) => false,
453+
| InlayKind::ClosingBraceHint => false,
454454
InlayKind::BindingModeHint => inlay_hint.label != "&",
455455
InlayKind::ParameterHint | InlayKind::LifetimeHint => true,
456456
}),
457457
label: lsp_types::InlayHintLabel::String(match inlay_hint.kind {
458458
InlayKind::ParameterHint if render_colons => format!("{}:", inlay_hint.label),
459459
InlayKind::TypeHint if render_colons => format!(": {}", inlay_hint.label),
460460
InlayKind::ClosureReturnTypeHint => format!(" -> {}", inlay_hint.label),
461-
_ => inlay_hint.label,
461+
_ => inlay_hint.label.clone(),
462462
}),
463463
kind: match inlay_hint.kind {
464464
InlayKind::ParameterHint => Some(lsp_types::InlayHintKind::PARAMETER),
@@ -469,22 +469,24 @@ pub(crate) fn inlay_hint(
469469
| InlayKind::GenericParamListHint
470470
| InlayKind::LifetimeHint
471471
| InlayKind::ImplicitReborrowHint
472-
| InlayKind::ClosingBraceHint(_) => None,
472+
| InlayKind::ClosingBraceHint => None,
473473
},
474474
text_edits: None,
475-
tooltip: None,
476-
data: match inlay_hint.kind {
477-
InlayKind::ClosingBraceHint(Some(offset)) => Some(
478-
to_value(lsp_ext::InlayHintResolveData {
479-
position: lsp_types::TextDocumentPositionParams {
480-
text_document: text_document.clone(),
481-
position: position(line_index, offset),
482-
},
483-
})
484-
.unwrap(),
485-
),
486-
_ => None,
487-
},
475+
tooltip: Some(lsp_types::InlayHintTooltip::String(inlay_hint.label)),
476+
data: inlay_hint.hover_trigger.map(|range_or_offset| {
477+
to_value(lsp_ext::InlayHintResolveData {
478+
text_document: text_document.clone(),
479+
position: match range_or_offset {
480+
ide::RangeOrOffset::Offset(offset) => {
481+
lsp_ext::PositionOrRange::Position(position(line_index, offset))
482+
}
483+
ide::RangeOrOffset::Range(text_range) => {
484+
lsp_ext::PositionOrRange::Range(range(line_index, text_range))
485+
}
486+
},
487+
})
488+
.unwrap()
489+
}),
488490
}
489491
}
490492

0 commit comments

Comments
 (0)