Merge #10805
10805: ide: dedupe or merge hover actions r=Veykril a=jhgg fixes #10780 Co-authored-by: Jake Heinz <jh@discordapp.com>
This commit is contained in:
commit
2507442382
@ -11,7 +11,7 @@
|
|||||||
base_db::FileRange,
|
base_db::FileRange,
|
||||||
defs::Definition,
|
defs::Definition,
|
||||||
helpers::{pick_best_token, FamousDefs},
|
helpers::{pick_best_token, FamousDefs},
|
||||||
RootDatabase,
|
FxIndexSet, RootDatabase,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, T};
|
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 struct HoverGotoTypeData {
|
||||||
pub mod_path: String,
|
pub mod_path: String,
|
||||||
pub nav: NavigationTarget,
|
pub nav: NavigationTarget,
|
||||||
@ -136,11 +136,12 @@ pub(crate) fn hover(
|
|||||||
.flatten()
|
.flatten()
|
||||||
.unique_by(|&(def, _)| def)
|
.unique_by(|&(def, _)| def)
|
||||||
.filter_map(|(def, node)| hover_for_definition(sema, file_id, def, &node, config))
|
.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.actions.extend(actions);
|
||||||
acc.markup = Markup::from(format!("{}\n---\n{}", acc.markup, markup));
|
acc.markup = Markup::from(format!("{}\n---\n{}", acc.markup, markup));
|
||||||
acc
|
acc
|
||||||
});
|
});
|
||||||
|
|
||||||
if result.is_none() {
|
if result.is_none() {
|
||||||
// fallbacks, show keywords or types
|
// fallbacks, show keywords or types
|
||||||
if let Some(res) = render::keyword(sema, config, &original_token) {
|
if let Some(res) = render::keyword(sema, config, &original_token) {
|
||||||
@ -152,7 +153,10 @@ pub(crate) fn hover(
|
|||||||
return res;
|
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(
|
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
|
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]
|
#[test]
|
||||||
fn test_hover_through_literal_string_in_builtin_macro() {
|
fn test_hover_through_literal_string_in_builtin_macro() {
|
||||||
check_hover_no_result(
|
check_hover_no_result(
|
||||||
@ -1750,9 +1783,6 @@ fn foo_$0test() {}
|
|||||||
cfg: None,
|
cfg: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
GoToType(
|
|
||||||
[],
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
@ -2749,21 +2779,21 @@ fn main() {
|
|||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
*f*
|
*f*
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
f: &i32
|
f: &i32
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
test::S
|
test::S
|
||||||
```
|
```
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
f: i32
|
f: i32
|
||||||
```
|
```
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user