diff options
author | Lukas Wirth <[email protected]> | 2021-06-04 14:49:43 +0100 |
---|---|---|
committer | Lukas Wirth <[email protected]> | 2021-06-04 14:54:55 +0100 |
commit | 07394316ff0c5454b3a9e854945ebd29b90259ec (patch) | |
tree | 43dc7fa25956c233f6a2b3384c134eb48a243a36 /crates | |
parent | cd46255d7e8bb59b93a32d5cb50581f418ca5f3b (diff) |
Add function references hover action
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ide/src/hover.rs | 29 | ||||
-rw-r--r-- | crates/rust-analyzer/src/config.rs | 4 | ||||
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 31 |
3 files changed, 63 insertions, 1 deletions
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 04598cd06..455a27e48 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -28,6 +28,7 @@ use crate::{ | |||
28 | #[derive(Clone, Debug, PartialEq, Eq)] | 28 | #[derive(Clone, Debug, PartialEq, Eq)] |
29 | pub struct HoverConfig { | 29 | pub struct HoverConfig { |
30 | pub implementations: bool, | 30 | pub implementations: bool, |
31 | pub references: bool, | ||
31 | pub run: bool, | 32 | pub run: bool, |
32 | pub debug: bool, | 33 | pub debug: bool, |
33 | pub goto_type_def: bool, | 34 | pub goto_type_def: bool, |
@@ -38,6 +39,7 @@ pub struct HoverConfig { | |||
38 | impl HoverConfig { | 39 | impl HoverConfig { |
39 | pub const NO_ACTIONS: Self = Self { | 40 | pub const NO_ACTIONS: Self = Self { |
40 | implementations: false, | 41 | implementations: false, |
42 | references: false, | ||
41 | run: false, | 43 | run: false, |
42 | debug: false, | 44 | debug: false, |
43 | goto_type_def: false, | 45 | goto_type_def: false, |
@@ -46,7 +48,7 @@ impl HoverConfig { | |||
46 | }; | 48 | }; |
47 | 49 | ||
48 | pub fn any(&self) -> bool { | 50 | pub fn any(&self) -> bool { |
49 | self.implementations || self.runnable() || self.goto_type_def | 51 | self.implementations || self.references || self.runnable() || self.goto_type_def |
50 | } | 52 | } |
51 | 53 | ||
52 | pub fn none(&self) -> bool { | 54 | pub fn none(&self) -> bool { |
@@ -62,6 +64,7 @@ impl HoverConfig { | |||
62 | pub enum HoverAction { | 64 | pub enum HoverAction { |
63 | Runnable(Runnable), | 65 | Runnable(Runnable), |
64 | Implementation(FilePosition), | 66 | Implementation(FilePosition), |
67 | Reference(FilePosition), | ||
65 | GoToType(Vec<HoverGotoTypeData>), | 68 | GoToType(Vec<HoverGotoTypeData>), |
66 | } | 69 | } |
67 | 70 | ||
@@ -148,6 +151,10 @@ pub(crate) fn hover( | |||
148 | res.actions.push(action); | 151 | res.actions.push(action); |
149 | } | 152 | } |
150 | 153 | ||
154 | if let Some(action) = show_fn_references_action(db, definition) { | ||
155 | res.actions.push(action); | ||
156 | } | ||
157 | |||
151 | if let Some(action) = runnable_action(&sema, definition, position.file_id) { | 158 | if let Some(action) = runnable_action(&sema, definition, position.file_id) { |
152 | res.actions.push(action); | 159 | res.actions.push(action); |
153 | } | 160 | } |
@@ -211,6 +218,18 @@ fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<Hov | |||
211 | adt.try_to_nav(db).map(to_action) | 218 | adt.try_to_nav(db).map(to_action) |
212 | } | 219 | } |
213 | 220 | ||
221 | fn show_fn_references_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> { | ||
222 | match def { | ||
223 | Definition::ModuleDef(ModuleDef::Function(it)) => it.try_to_nav(db).map(|nav_target| { | ||
224 | HoverAction::Reference(FilePosition { | ||
225 | file_id: nav_target.file_id, | ||
226 | offset: nav_target.focus_or_full_range().start(), | ||
227 | }) | ||
228 | }), | ||
229 | _ => None, | ||
230 | } | ||
231 | } | ||
232 | |||
214 | fn runnable_action( | 233 | fn runnable_action( |
215 | sema: &Semantics<RootDatabase>, | 234 | sema: &Semantics<RootDatabase>, |
216 | def: Definition, | 235 | def: Definition, |
@@ -2377,6 +2396,14 @@ fn foo_$0test() {} | |||
2377 | "#, | 2396 | "#, |
2378 | expect![[r#" | 2397 | expect![[r#" |
2379 | [ | 2398 | [ |
2399 | Reference( | ||
2400 | FilePosition { | ||
2401 | file_id: FileId( | ||
2402 | 0, | ||
2403 | ), | ||
2404 | offset: 11, | ||
2405 | }, | ||
2406 | ), | ||
2380 | Runnable( | 2407 | Runnable( |
2381 | Runnable { | 2408 | Runnable { |
2382 | nav: NavigationTarget { | 2409 | nav: NavigationTarget { |
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index d1f3c1b06..3b20d741a 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs | |||
@@ -152,6 +152,9 @@ config_data! { | |||
152 | /// Whether to show `Implementations` action. Only applies when | 152 | /// Whether to show `Implementations` action. Only applies when |
153 | /// `#rust-analyzer.hoverActions.enable#` is set. | 153 | /// `#rust-analyzer.hoverActions.enable#` is set. |
154 | hoverActions_implementations: bool = "true", | 154 | hoverActions_implementations: bool = "true", |
155 | /// Whether to show `References` action. Only applies when | ||
156 | /// `#rust-analyzer.hoverActions.enable#` is set. | ||
157 | hoverActions_references: bool = "false", | ||
155 | /// Whether to show `Run` action. Only applies when | 158 | /// Whether to show `Run` action. Only applies when |
156 | /// `#rust-analyzer.hoverActions.enable#` is set. | 159 | /// `#rust-analyzer.hoverActions.enable#` is set. |
157 | hoverActions_run: bool = "true", | 160 | hoverActions_run: bool = "true", |
@@ -719,6 +722,7 @@ impl Config { | |||
719 | HoverConfig { | 722 | HoverConfig { |
720 | implementations: self.data.hoverActions_enable | 723 | implementations: self.data.hoverActions_enable |
721 | && self.data.hoverActions_implementations, | 724 | && self.data.hoverActions_implementations, |
725 | references: self.data.hoverActions_enable && self.data.hoverActions_references, | ||
722 | run: self.data.hoverActions_enable && self.data.hoverActions_run, | 726 | run: self.data.hoverActions_enable && self.data.hoverActions_run, |
723 | debug: self.data.hoverActions_enable && self.data.hoverActions_debug, | 727 | debug: self.data.hoverActions_enable && self.data.hoverActions_debug, |
724 | goto_type_def: self.data.hoverActions_enable && self.data.hoverActions_gotoTypeDef, | 728 | goto_type_def: self.data.hoverActions_enable && self.data.hoverActions_gotoTypeDef, |
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 49ee4b922..70511c5ca 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -1506,6 +1506,36 @@ fn show_impl_command_link( | |||
1506 | None | 1506 | None |
1507 | } | 1507 | } |
1508 | 1508 | ||
1509 | fn show_ref_command_link( | ||
1510 | snap: &GlobalStateSnapshot, | ||
1511 | position: &FilePosition, | ||
1512 | ) -> Option<lsp_ext::CommandLinkGroup> { | ||
1513 | if snap.config.hover().implementations { | ||
1514 | if let Some(ref_search_res) = snap.analysis.find_all_refs(*position, None).unwrap_or(None) { | ||
1515 | let uri = to_proto::url(snap, position.file_id); | ||
1516 | let line_index = snap.file_line_index(position.file_id).ok()?; | ||
1517 | let position = to_proto::position(&line_index, position.offset); | ||
1518 | let locations: Vec<_> = ref_search_res | ||
1519 | .references | ||
1520 | .into_iter() | ||
1521 | .flat_map(|(file_id, ranges)| { | ||
1522 | ranges.into_iter().filter_map(move |(range, _)| { | ||
1523 | to_proto::location(snap, FileRange { file_id, range }).ok() | ||
1524 | }) | ||
1525 | }) | ||
1526 | .collect(); | ||
1527 | let title = to_proto::reference_title(locations.len()); | ||
1528 | let command = to_proto::command::show_references(title, &uri, position, locations); | ||
1529 | |||
1530 | return Some(lsp_ext::CommandLinkGroup { | ||
1531 | commands: vec![to_command_link(command, "Go to references".into())], | ||
1532 | ..Default::default() | ||
1533 | }); | ||
1534 | } | ||
1535 | } | ||
1536 | None | ||
1537 | } | ||
1538 | |||
1509 | fn runnable_action_links( | 1539 | fn runnable_action_links( |
1510 | snap: &GlobalStateSnapshot, | 1540 | snap: &GlobalStateSnapshot, |
1511 | runnable: Runnable, | 1541 | runnable: Runnable, |
@@ -1566,6 +1596,7 @@ fn prepare_hover_actions( | |||
1566 | .iter() | 1596 | .iter() |
1567 | .filter_map(|it| match it { | 1597 | .filter_map(|it| match it { |
1568 | HoverAction::Implementation(position) => show_impl_command_link(snap, position), | 1598 | HoverAction::Implementation(position) => show_impl_command_link(snap, position), |
1599 | HoverAction::Reference(position) => show_ref_command_link(snap, position), | ||
1569 | HoverAction::Runnable(r) => runnable_action_links(snap, r.clone()), | 1600 | HoverAction::Runnable(r) => runnable_action_links(snap, r.clone()), |
1570 | HoverAction::GoToType(targets) => goto_type_action_links(snap, targets), | 1601 | HoverAction::GoToType(targets) => goto_type_action_links(snap, targets), |
1571 | }) | 1602 | }) |