mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 04:19:13 +00:00
ide: dedupe or merge hover actions
This commit is contained in:
parent
cfa26c3ac3
commit
c28dc00b39
2 changed files with 94 additions and 20 deletions
|
@ -11,7 +11,7 @@ use ide_db::{
|
|||
base_db::FileRange,
|
||||
defs::Definition,
|
||||
helpers::{pick_best_token, FamousDefs},
|
||||
RootDatabase,
|
||||
FxIndexSet, RootDatabase,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, T};
|
||||
|
@ -69,7 +69,7 @@ impl HoverAction {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct HoverGotoTypeData {
|
||||
pub mod_path: String,
|
||||
pub nav: NavigationTarget,
|
||||
|
@ -136,11 +136,12 @@ pub(crate) fn hover(
|
|||
.flatten()
|
||||
.unique_by(|&(def, _)| def)
|
||||
.filter_map(|(def, node)| hover_for_definition(sema, file_id, def, &node, config))
|
||||
.reduce(|mut acc, HoverResult { markup, actions }| {
|
||||
.reduce(|mut acc: HoverResult, HoverResult { markup, actions }| {
|
||||
acc.actions.extend(actions);
|
||||
acc.markup = Markup::from(format!("{}\n---\n{}", acc.markup, markup));
|
||||
acc
|
||||
});
|
||||
|
||||
if result.is_none() {
|
||||
// fallbacks, show keywords or types
|
||||
if let Some(res) = render::keyword(sema, config, &original_token) {
|
||||
|
@ -152,7 +153,10 @@ pub(crate) fn hover(
|
|||
return res;
|
||||
}
|
||||
}
|
||||
result.map(|res| RangeInfo::new(original_token.text_range(), res))
|
||||
result.map(|mut res: HoverResult| {
|
||||
res.actions = dedupe_or_merge_hover_actions(res.actions);
|
||||
RangeInfo::new(original_token.text_range(), res)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn hover_for_definition(
|
||||
|
@ -341,3 +345,43 @@ fn walk_and_push_ty(
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn dedupe_or_merge_hover_actions(actions: Vec<HoverAction>) -> Vec<HoverAction> {
|
||||
let mut deduped_actions = Vec::with_capacity(actions.len());
|
||||
let mut go_to_type_targets = FxIndexSet::default();
|
||||
|
||||
let mut seen_implementation = false;
|
||||
let mut seen_reference = false;
|
||||
let mut seen_runnable = false;
|
||||
for action in actions {
|
||||
match action {
|
||||
HoverAction::GoToType(targets) => {
|
||||
go_to_type_targets.extend(targets);
|
||||
}
|
||||
HoverAction::Implementation(..) => {
|
||||
if !seen_implementation {
|
||||
seen_implementation = true;
|
||||
deduped_actions.push(action);
|
||||
}
|
||||
}
|
||||
HoverAction::Reference(..) => {
|
||||
if !seen_reference {
|
||||
seen_reference = true;
|
||||
deduped_actions.push(action);
|
||||
}
|
||||
}
|
||||
HoverAction::Runnable(..) => {
|
||||
if !seen_runnable {
|
||||
seen_runnable = true;
|
||||
deduped_actions.push(action);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if !go_to_type_targets.is_empty() {
|
||||
deduped_actions.push(HoverAction::GoToType(go_to_type_targets.into_iter().collect()));
|
||||
}
|
||||
|
||||
deduped_actions
|
||||
}
|
||||
|
|
|
@ -1135,6 +1135,39 @@ fn foo() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hover_multiple_actions() {
|
||||
check_actions(
|
||||
r#"
|
||||
struct Bar;
|
||||
struct Foo { bar: Bar }
|
||||
|
||||
fn foo(Foo { b$0ar }: &Foo) {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
[
|
||||
GoToType(
|
||||
[
|
||||
HoverGotoTypeData {
|
||||
mod_path: "test::Bar",
|
||||
nav: NavigationTarget {
|
||||
file_id: FileId(
|
||||
0,
|
||||
),
|
||||
full_range: 0..11,
|
||||
focus_range: 7..10,
|
||||
name: "Bar",
|
||||
kind: Struct,
|
||||
description: "struct Bar",
|
||||
},
|
||||
},
|
||||
],
|
||||
),
|
||||
]
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hover_through_literal_string_in_builtin_macro() {
|
||||
check_hover_no_result(
|
||||
|
@ -1750,9 +1783,6 @@ fn foo_$0test() {}
|
|||
cfg: None,
|
||||
},
|
||||
),
|
||||
GoToType(
|
||||
[],
|
||||
),
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue