Skip to content

Commit c28dc00

Browse files
committed
ide: dedupe or merge hover actions
1 parent cfa26c3 commit c28dc00

File tree

2 files changed

+94
-20
lines changed

2 files changed

+94
-20
lines changed

crates/ide/src/hover.rs

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use ide_db::{
1111
base_db::FileRange,
1212
defs::Definition,
1313
helpers::{pick_best_token, FamousDefs},
14-
RootDatabase,
14+
FxIndexSet, RootDatabase,
1515
};
1616
use itertools::Itertools;
1717
use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, T};
@@ -69,7 +69,7 @@ impl HoverAction {
6969
}
7070
}
7171

72-
#[derive(Debug, Clone, Eq, PartialEq)]
72+
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
7373
pub struct HoverGotoTypeData {
7474
pub mod_path: String,
7575
pub nav: NavigationTarget,
@@ -136,11 +136,12 @@ pub(crate) fn hover(
136136
.flatten()
137137
.unique_by(|&(def, _)| def)
138138
.filter_map(|(def, node)| hover_for_definition(sema, file_id, def, &node, config))
139-
.reduce(|mut acc, HoverResult { markup, actions }| {
139+
.reduce(|mut acc: HoverResult, HoverResult { markup, actions }| {
140140
acc.actions.extend(actions);
141141
acc.markup = Markup::from(format!("{}\n---\n{}", acc.markup, markup));
142142
acc
143143
});
144+
144145
if result.is_none() {
145146
// fallbacks, show keywords or types
146147
if let Some(res) = render::keyword(sema, config, &original_token) {
@@ -152,7 +153,10 @@ pub(crate) fn hover(
152153
return res;
153154
}
154155
}
155-
result.map(|res| RangeInfo::new(original_token.text_range(), res))
156+
result.map(|mut res: HoverResult| {
157+
res.actions = dedupe_or_merge_hover_actions(res.actions);
158+
RangeInfo::new(original_token.text_range(), res)
159+
})
156160
}
157161

158162
pub(crate) fn hover_for_definition(
@@ -341,3 +345,43 @@ fn walk_and_push_ty(
341345
}
342346
});
343347
}
348+
349+
fn dedupe_or_merge_hover_actions(actions: Vec<HoverAction>) -> Vec<HoverAction> {
350+
let mut deduped_actions = Vec::with_capacity(actions.len());
351+
let mut go_to_type_targets = FxIndexSet::default();
352+
353+
let mut seen_implementation = false;
354+
let mut seen_reference = false;
355+
let mut seen_runnable = false;
356+
for action in actions {
357+
match action {
358+
HoverAction::GoToType(targets) => {
359+
go_to_type_targets.extend(targets);
360+
}
361+
HoverAction::Implementation(..) => {
362+
if !seen_implementation {
363+
seen_implementation = true;
364+
deduped_actions.push(action);
365+
}
366+
}
367+
HoverAction::Reference(..) => {
368+
if !seen_reference {
369+
seen_reference = true;
370+
deduped_actions.push(action);
371+
}
372+
}
373+
HoverAction::Runnable(..) => {
374+
if !seen_runnable {
375+
seen_runnable = true;
376+
deduped_actions.push(action);
377+
}
378+
}
379+
};
380+
}
381+
382+
if !go_to_type_targets.is_empty() {
383+
deduped_actions.push(HoverAction::GoToType(go_to_type_targets.into_iter().collect()));
384+
}
385+
386+
deduped_actions
387+
}

crates/ide/src/hover/tests.rs

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ m!(ab$0c);
173173
---
174174
175175
Outer
176-
"#]],
176+
"#]],
177177
);
178178
}
179179

@@ -1135,6 +1135,39 @@ fn foo() {
11351135
);
11361136
}
11371137

1138+
#[test]
1139+
fn test_hover_multiple_actions() {
1140+
check_actions(
1141+
r#"
1142+
struct Bar;
1143+
struct Foo { bar: Bar }
1144+
1145+
fn foo(Foo { b$0ar }: &Foo) {}
1146+
"#,
1147+
expect![[r#"
1148+
[
1149+
GoToType(
1150+
[
1151+
HoverGotoTypeData {
1152+
mod_path: "test::Bar",
1153+
nav: NavigationTarget {
1154+
file_id: FileId(
1155+
0,
1156+
),
1157+
full_range: 0..11,
1158+
focus_range: 7..10,
1159+
name: "Bar",
1160+
kind: Struct,
1161+
description: "struct Bar",
1162+
},
1163+
},
1164+
],
1165+
),
1166+
]
1167+
"#]],
1168+
)
1169+
}
1170+
11381171
#[test]
11391172
fn test_hover_through_literal_string_in_builtin_macro() {
11401173
check_hover_no_result(
@@ -1750,9 +1783,6 @@ fn foo_$0test() {}
17501783
cfg: None,
17511784
},
17521785
),
1753-
GoToType(
1754-
[],
1755-
),
17561786
]
17571787
"#]],
17581788
);
@@ -2749,21 +2779,21 @@ fn main() {
27492779
}
27502780
"#,
27512781
expect![[r#"
2752-
*f*
2782+
*f*
27532783
2754-
```rust
2755-
f: &i32
2756-
```
2757-
---
2784+
```rust
2785+
f: &i32
2786+
```
2787+
---
27582788
2759-
```rust
2760-
test::S
2761-
```
2789+
```rust
2790+
test::S
2791+
```
27622792
2763-
```rust
2764-
f: i32
2765-
```
2766-
"#]],
2793+
```rust
2794+
f: i32
2795+
```
2796+
"#]],
27672797
);
27682798
}
27692799

0 commit comments

Comments
 (0)