Trigger hover requests on closing brace hints
This commit is contained in:
parent
0756719a30
commit
a2ec010185
@ -8,7 +8,8 @@
|
||||
use stdx::to_lower_snake_case;
|
||||
use syntax::{
|
||||
ast::{self, AstNode, HasArgList, HasGenericParams, HasName, UnaryOp},
|
||||
match_ast, Direction, NodeOrToken, SmolStr, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, T,
|
||||
match_ast, Direction, NodeOrToken, SmolStr, SyntaxKind, SyntaxNode, SyntaxToken, TextRange,
|
||||
TextSize, T,
|
||||
};
|
||||
|
||||
use crate::FileId;
|
||||
@ -47,7 +48,7 @@ pub enum ReborrowHints {
|
||||
pub enum InlayKind {
|
||||
BindingModeHint,
|
||||
ChainingHint,
|
||||
ClosingBraceHint,
|
||||
ClosingBraceHint(Option<TextSize>),
|
||||
ClosureReturnTypeHint,
|
||||
GenericParamListHint,
|
||||
ImplicitReborrowHint,
|
||||
@ -164,8 +165,10 @@ fn closing_brace_hints(
|
||||
) -> Option<()> {
|
||||
let min_lines = config.closing_brace_hints_min_lines?;
|
||||
|
||||
let name = |it: ast::Name| it.syntax().text_range().start();
|
||||
|
||||
let mut closing_token;
|
||||
let label = if let Some(item_list) = ast::AssocItemList::cast(node.clone()) {
|
||||
let (label, name_offset) = if let Some(item_list) = ast::AssocItemList::cast(node.clone()) {
|
||||
closing_token = item_list.r_curly_token()?;
|
||||
|
||||
let parent = item_list.syntax().parent()?;
|
||||
@ -176,13 +179,13 @@ fn closing_brace_hints(
|
||||
let ty = imp.self_ty(sema.db);
|
||||
let trait_ = imp.trait_(sema.db);
|
||||
|
||||
match trait_ {
|
||||
(match trait_ {
|
||||
Some(tr) => format!("impl {} for {}", tr.name(sema.db), ty.display_truncated(sema.db, config.max_length)),
|
||||
None => format!("impl {}", ty.display_truncated(sema.db, config.max_length)),
|
||||
}
|
||||
}, None)
|
||||
},
|
||||
ast::Trait(tr) => {
|
||||
format!("trait {}", tr.name()?)
|
||||
(format!("trait {}", tr.name()?), tr.name().map(name))
|
||||
},
|
||||
_ => return None,
|
||||
}
|
||||
@ -191,7 +194,7 @@ fn closing_brace_hints(
|
||||
closing_token = list.r_curly_token()?;
|
||||
|
||||
let module = ast::Module::cast(list.syntax().parent()?)?;
|
||||
format!("mod {}", module.name()?)
|
||||
(format!("mod {}", module.name()?), module.name().map(name))
|
||||
} else if let Some(block) = ast::BlockExpr::cast(node.clone()) {
|
||||
closing_token = block.stmt_list()?.r_curly_token()?;
|
||||
|
||||
@ -201,14 +204,14 @@ fn closing_brace_hints(
|
||||
ast::Fn(it) => {
|
||||
// FIXME: this could include parameters, but `HirDisplay` prints too much info
|
||||
// and doesn't respect the max length either, so the hints end up way too long
|
||||
format!("fn {}", it.name()?)
|
||||
(format!("fn {}", it.name()?), it.name().map(name))
|
||||
},
|
||||
ast::Static(it) => format!("static {}", it.name()?),
|
||||
ast::Static(it) => (format!("static {}", it.name()?), it.name().map(name)),
|
||||
ast::Const(it) => {
|
||||
if it.underscore_token().is_some() {
|
||||
"const _".into()
|
||||
("const _".into(), None)
|
||||
} else {
|
||||
format!("const {}", it.name()?)
|
||||
(format!("const {}", it.name()?), it.name().map(name))
|
||||
}
|
||||
},
|
||||
_ => return None,
|
||||
@ -221,7 +224,10 @@ fn closing_brace_hints(
|
||||
}
|
||||
closing_token = last_token;
|
||||
|
||||
format!("{}!", mac.path()?)
|
||||
(
|
||||
format!("{}!", mac.path()?),
|
||||
mac.path().and_then(|it| it.segment()).map(|it| it.syntax().text_range().start()),
|
||||
)
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
@ -247,7 +253,7 @@ fn closing_brace_hints(
|
||||
|
||||
acc.push(InlayHint {
|
||||
range: closing_token.text_range(),
|
||||
kind: InlayKind::ClosingBraceHint,
|
||||
kind: InlayKind::ClosingBraceHint(name_offset),
|
||||
label,
|
||||
});
|
||||
|
||||
|
@ -1343,21 +1343,63 @@ pub(crate) fn handle_inlay_hints(
|
||||
snap.analysis
|
||||
.inlay_hints(&inlay_hints_config, file_id, Some(range))?
|
||||
.into_iter()
|
||||
.map(|it| to_proto::inlay_hint(inlay_hints_config.render_colons, &line_index, it))
|
||||
.map(|it| {
|
||||
to_proto::inlay_hint(
|
||||
&line_index,
|
||||
¶ms.text_document,
|
||||
inlay_hints_config.render_colons,
|
||||
it,
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn handle_inlay_hints_resolve(
|
||||
_snap: GlobalStateSnapshot,
|
||||
snap: GlobalStateSnapshot,
|
||||
mut hint: InlayHint,
|
||||
) -> Result<InlayHint> {
|
||||
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 _p = profile::span("handle_inlay_hints_resolve");
|
||||
let succ = (|| {
|
||||
let data = match hint.data.take() {
|
||||
Some(it) => it,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
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 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(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(hint)
|
||||
}
|
||||
|
||||
|
@ -518,6 +518,11 @@ pub struct CompletionResolveData {
|
||||
pub imports: Vec<CompletionImport>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct InlayHintResolveData {
|
||||
pub position: lsp_types::TextDocumentPositionParams,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct CompletionImport {
|
||||
pub full_import_path: String,
|
||||
|
@ -415,8 +415,9 @@ pub(crate) fn signature_help(
|
||||
}
|
||||
|
||||
pub(crate) fn inlay_hint(
|
||||
render_colons: bool,
|
||||
line_index: &LineIndex,
|
||||
text_document: &lsp_types::TextDocumentIdentifier,
|
||||
render_colons: bool,
|
||||
inlay_hint: InlayHint,
|
||||
) -> lsp_types::InlayHint {
|
||||
lsp_types::InlayHint {
|
||||
@ -431,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
|
||||
@ -449,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,
|
||||
}),
|
||||
@ -468,11 +469,22 @@ pub(crate) fn inlay_hint(
|
||||
| InlayKind::GenericParamListHint
|
||||
| InlayKind::LifetimeHint
|
||||
| InlayKind::ImplicitReborrowHint
|
||||
| InlayKind::ClosingBraceHint => None,
|
||||
| InlayKind::ClosingBraceHint(_) => None,
|
||||
},
|
||||
text_edits: None,
|
||||
tooltip: None,
|
||||
data: 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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user