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

Commit a2ec010

Browse files
committed
Trigger hover requests on closing brace hints
1 parent 0756719 commit a2ec010

File tree

4 files changed

+91
-26
lines changed

4 files changed

+91
-26
lines changed

crates/ide/src/inlay_hints.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ use itertools::Itertools;
88
use stdx::to_lower_snake_case;
99
use syntax::{
1010
ast::{self, AstNode, HasArgList, HasGenericParams, HasName, UnaryOp},
11-
match_ast, Direction, NodeOrToken, SmolStr, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, T,
11+
match_ast, Direction, NodeOrToken, SmolStr, SyntaxKind, SyntaxNode, SyntaxToken, TextRange,
12+
TextSize, T,
1213
};
1314

1415
use crate::FileId;
@@ -47,7 +48,7 @@ pub enum ReborrowHints {
4748
pub enum InlayKind {
4849
BindingModeHint,
4950
ChainingHint,
50-
ClosingBraceHint,
51+
ClosingBraceHint(Option<TextSize>),
5152
ClosureReturnTypeHint,
5253
GenericParamListHint,
5354
ImplicitReborrowHint,
@@ -164,8 +165,10 @@ fn closing_brace_hints(
164165
) -> Option<()> {
165166
let min_lines = config.closing_brace_hints_min_lines?;
166167

168+
let name = |it: ast::Name| it.syntax().text_range().start();
169+
167170
let mut closing_token;
168-
let label = if let Some(item_list) = ast::AssocItemList::cast(node.clone()) {
171+
let (label, name_offset) = if let Some(item_list) = ast::AssocItemList::cast(node.clone()) {
169172
closing_token = item_list.r_curly_token()?;
170173

171174
let parent = item_list.syntax().parent()?;
@@ -176,13 +179,13 @@ fn closing_brace_hints(
176179
let ty = imp.self_ty(sema.db);
177180
let trait_ = imp.trait_(sema.db);
178181

179-
match trait_ {
182+
(match trait_ {
180183
Some(tr) => format!("impl {} for {}", tr.name(sema.db), ty.display_truncated(sema.db, config.max_length)),
181184
None => format!("impl {}", ty.display_truncated(sema.db, config.max_length)),
182-
}
185+
}, None)
183186
},
184187
ast::Trait(tr) => {
185-
format!("trait {}", tr.name()?)
188+
(format!("trait {}", tr.name()?), tr.name().map(name))
186189
},
187190
_ => return None,
188191
}
@@ -191,7 +194,7 @@ fn closing_brace_hints(
191194
closing_token = list.r_curly_token()?;
192195

193196
let module = ast::Module::cast(list.syntax().parent()?)?;
194-
format!("mod {}", module.name()?)
197+
(format!("mod {}", module.name()?), module.name().map(name))
195198
} else if let Some(block) = ast::BlockExpr::cast(node.clone()) {
196199
closing_token = block.stmt_list()?.r_curly_token()?;
197200

@@ -201,14 +204,14 @@ fn closing_brace_hints(
201204
ast::Fn(it) => {
202205
// FIXME: this could include parameters, but `HirDisplay` prints too much info
203206
// and doesn't respect the max length either, so the hints end up way too long
204-
format!("fn {}", it.name()?)
207+
(format!("fn {}", it.name()?), it.name().map(name))
205208
},
206-
ast::Static(it) => format!("static {}", it.name()?),
209+
ast::Static(it) => (format!("static {}", it.name()?), it.name().map(name)),
207210
ast::Const(it) => {
208211
if it.underscore_token().is_some() {
209-
"const _".into()
212+
("const _".into(), None)
210213
} else {
211-
format!("const {}", it.name()?)
214+
(format!("const {}", it.name()?), it.name().map(name))
212215
}
213216
},
214217
_ => return None,
@@ -221,7 +224,10 @@ fn closing_brace_hints(
221224
}
222225
closing_token = last_token;
223226

224-
format!("{}!", mac.path()?)
227+
(
228+
format!("{}!", mac.path()?),
229+
mac.path().and_then(|it| it.segment()).map(|it| it.syntax().text_range().start()),
230+
)
225231
} else {
226232
return None;
227233
};
@@ -247,7 +253,7 @@ fn closing_brace_hints(
247253

248254
acc.push(InlayHint {
249255
range: closing_token.text_range(),
250-
kind: InlayKind::ClosingBraceHint,
256+
kind: InlayKind::ClosingBraceHint(name_offset),
251257
label,
252258
});
253259

crates/rust-analyzer/src/handlers.rs

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,21 +1343,63 @@ pub(crate) fn handle_inlay_hints(
13431343
snap.analysis
13441344
.inlay_hints(&inlay_hints_config, file_id, Some(range))?
13451345
.into_iter()
1346-
.map(|it| to_proto::inlay_hint(inlay_hints_config.render_colons, &line_index, it))
1346+
.map(|it| {
1347+
to_proto::inlay_hint(
1348+
&line_index,
1349+
&params.text_document,
1350+
inlay_hints_config.render_colons,
1351+
it,
1352+
)
1353+
})
13471354
.collect(),
13481355
))
13491356
}
13501357

13511358
pub(crate) fn handle_inlay_hints_resolve(
1352-
_snap: GlobalStateSnapshot,
1359+
snap: GlobalStateSnapshot,
13531360
mut hint: InlayHint,
13541361
) -> Result<InlayHint> {
1355-
if let lsp_types::InlayHintLabel::String(s) = &hint.label {
1356-
hint.tooltip = Some(lsp_types::InlayHintTooltip::MarkupContent(lsp_types::MarkupContent {
1357-
kind: lsp_types::MarkupKind::PlainText,
1358-
value: s.clone(),
1359-
}));
1362+
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+
};
1368+
1369+
let resolve_data: lsp_ext::InlayHintResolveData = serde_json::from_value(data)?;
1370+
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+
};
1380+
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+
}
13601401
}
1402+
13611403
Ok(hint)
13621404
}
13631405

crates/rust-analyzer/src/lsp_ext.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,11 @@ pub struct CompletionResolveData {
518518
pub imports: Vec<CompletionImport>,
519519
}
520520

521+
#[derive(Debug, Serialize, Deserialize)]
522+
pub struct InlayHintResolveData {
523+
pub position: lsp_types::TextDocumentPositionParams,
524+
}
525+
521526
#[derive(Debug, Serialize, Deserialize)]
522527
pub struct CompletionImport {
523528
pub full_import_path: String,

crates/rust-analyzer/src/to_proto.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,9 @@ pub(crate) fn signature_help(
415415
}
416416

417417
pub(crate) fn inlay_hint(
418-
render_colons: bool,
419418
line_index: &LineIndex,
419+
text_document: &lsp_types::TextDocumentIdentifier,
420+
render_colons: bool,
420421
inlay_hint: InlayHint,
421422
) -> lsp_types::InlayHint {
422423
lsp_types::InlayHint {
@@ -431,11 +432,11 @@ pub(crate) fn inlay_hint(
431432
| InlayKind::ChainingHint
432433
| InlayKind::GenericParamListHint
433434
| InlayKind::LifetimeHint
434-
| InlayKind::ClosingBraceHint => position(line_index, inlay_hint.range.end()),
435+
| InlayKind::ClosingBraceHint(_) => position(line_index, inlay_hint.range.end()),
435436
},
436437
padding_left: Some(match inlay_hint.kind {
437438
InlayKind::TypeHint => !render_colons,
438-
InlayKind::ChainingHint | InlayKind::ClosingBraceHint => true,
439+
InlayKind::ChainingHint | InlayKind::ClosingBraceHint(_) => true,
439440
InlayKind::BindingModeHint
440441
| InlayKind::ClosureReturnTypeHint
441442
| InlayKind::GenericParamListHint
@@ -449,7 +450,7 @@ pub(crate) fn inlay_hint(
449450
| InlayKind::GenericParamListHint
450451
| InlayKind::ImplicitReborrowHint
451452
| InlayKind::TypeHint
452-
| InlayKind::ClosingBraceHint => false,
453+
| InlayKind::ClosingBraceHint(_) => false,
453454
InlayKind::BindingModeHint => inlay_hint.label != "&",
454455
InlayKind::ParameterHint | InlayKind::LifetimeHint => true,
455456
}),
@@ -468,11 +469,22 @@ pub(crate) fn inlay_hint(
468469
| InlayKind::GenericParamListHint
469470
| InlayKind::LifetimeHint
470471
| InlayKind::ImplicitReborrowHint
471-
| InlayKind::ClosingBraceHint => None,
472+
| InlayKind::ClosingBraceHint(_) => None,
472473
},
473474
text_edits: None,
474475
tooltip: None,
475-
data: 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+
},
476488
}
477489
}
478490

0 commit comments

Comments
 (0)