aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ide/src/hover.rs29
-rw-r--r--crates/rust-analyzer/src/config.rs4
-rw-r--r--crates/rust-analyzer/src/handlers.rs31
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)]
29pub struct HoverConfig { 29pub 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 {
38impl HoverConfig { 39impl 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 {
62pub enum HoverAction { 64pub 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
221fn 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
214fn runnable_action( 233fn 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
1509fn 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
1509fn runnable_action_links( 1539fn 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 })