ide: dedupe or merge hover actions
This commit is contained in:
parent
cfa26c3ac3
commit
c28dc00b39
@ -11,7 +11,7 @@
|
||||
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 @@ fn goto_type_from_targets(db: &RootDatabase, targets: Vec<hir::ModuleDef>) -> Se
|
||||
}
|
||||
}
|
||||
|
||||
#[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
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ fn abc()
|
||||
---
|
||||
|
||||
Outer
|
||||
"#]],
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@ -1135,6 +1135,39 @@ fn bar() -> bool
|
||||
);
|
||||
}
|
||||
|
||||
#[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(
|
||||
[],
|
||||
),
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
@ -2749,21 +2779,21 @@ fn main() {
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
*f*
|
||||
*f*
|
||||
|
||||
```rust
|
||||
f: &i32
|
||||
```
|
||||
---
|
||||
```rust
|
||||
f: &i32
|
||||
```
|
||||
---
|
||||
|
||||
```rust
|
||||
test::S
|
||||
```
|
||||
```rust
|
||||
test::S
|
||||
```
|
||||
|
||||
```rust
|
||||
f: i32
|
||||
```
|
||||
"#]],
|
||||
```rust
|
||||
f: i32
|
||||
```
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user