mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
Add function references hover action
This commit is contained in:
parent
cd46255d7e
commit
07394316ff
6 changed files with 75 additions and 1 deletions
|
@ -28,6 +28,7 @@ use crate::{
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct HoverConfig {
|
pub struct HoverConfig {
|
||||||
pub implementations: bool,
|
pub implementations: bool,
|
||||||
|
pub references: bool,
|
||||||
pub run: bool,
|
pub run: bool,
|
||||||
pub debug: bool,
|
pub debug: bool,
|
||||||
pub goto_type_def: bool,
|
pub goto_type_def: bool,
|
||||||
|
@ -38,6 +39,7 @@ pub struct HoverConfig {
|
||||||
impl HoverConfig {
|
impl HoverConfig {
|
||||||
pub const NO_ACTIONS: Self = Self {
|
pub const NO_ACTIONS: Self = Self {
|
||||||
implementations: false,
|
implementations: false,
|
||||||
|
references: false,
|
||||||
run: false,
|
run: false,
|
||||||
debug: false,
|
debug: false,
|
||||||
goto_type_def: false,
|
goto_type_def: false,
|
||||||
|
@ -46,7 +48,7 @@ impl HoverConfig {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn any(&self) -> bool {
|
pub fn any(&self) -> bool {
|
||||||
self.implementations || self.runnable() || self.goto_type_def
|
self.implementations || self.references || self.runnable() || self.goto_type_def
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn none(&self) -> bool {
|
pub fn none(&self) -> bool {
|
||||||
|
@ -62,6 +64,7 @@ impl HoverConfig {
|
||||||
pub enum HoverAction {
|
pub enum HoverAction {
|
||||||
Runnable(Runnable),
|
Runnable(Runnable),
|
||||||
Implementation(FilePosition),
|
Implementation(FilePosition),
|
||||||
|
Reference(FilePosition),
|
||||||
GoToType(Vec<HoverGotoTypeData>),
|
GoToType(Vec<HoverGotoTypeData>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +151,10 @@ pub(crate) fn hover(
|
||||||
res.actions.push(action);
|
res.actions.push(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(action) = show_fn_references_action(db, definition) {
|
||||||
|
res.actions.push(action);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(action) = runnable_action(&sema, definition, position.file_id) {
|
if let Some(action) = runnable_action(&sema, definition, position.file_id) {
|
||||||
res.actions.push(action);
|
res.actions.push(action);
|
||||||
}
|
}
|
||||||
|
@ -211,6 +218,18 @@ fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<Hov
|
||||||
adt.try_to_nav(db).map(to_action)
|
adt.try_to_nav(db).map(to_action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn show_fn_references_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> {
|
||||||
|
match def {
|
||||||
|
Definition::ModuleDef(ModuleDef::Function(it)) => it.try_to_nav(db).map(|nav_target| {
|
||||||
|
HoverAction::Reference(FilePosition {
|
||||||
|
file_id: nav_target.file_id,
|
||||||
|
offset: nav_target.focus_or_full_range().start(),
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn runnable_action(
|
fn runnable_action(
|
||||||
sema: &Semantics<RootDatabase>,
|
sema: &Semantics<RootDatabase>,
|
||||||
def: Definition,
|
def: Definition,
|
||||||
|
@ -2377,6 +2396,14 @@ fn foo_$0test() {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
[
|
[
|
||||||
|
Reference(
|
||||||
|
FilePosition {
|
||||||
|
file_id: FileId(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
offset: 11,
|
||||||
|
},
|
||||||
|
),
|
||||||
Runnable(
|
Runnable(
|
||||||
Runnable {
|
Runnable {
|
||||||
nav: NavigationTarget {
|
nav: NavigationTarget {
|
||||||
|
|
|
@ -152,6 +152,9 @@ config_data! {
|
||||||
/// Whether to show `Implementations` action. Only applies when
|
/// Whether to show `Implementations` action. Only applies when
|
||||||
/// `#rust-analyzer.hoverActions.enable#` is set.
|
/// `#rust-analyzer.hoverActions.enable#` is set.
|
||||||
hoverActions_implementations: bool = "true",
|
hoverActions_implementations: bool = "true",
|
||||||
|
/// Whether to show `References` action. Only applies when
|
||||||
|
/// `#rust-analyzer.hoverActions.enable#` is set.
|
||||||
|
hoverActions_references: bool = "false",
|
||||||
/// Whether to show `Run` action. Only applies when
|
/// Whether to show `Run` action. Only applies when
|
||||||
/// `#rust-analyzer.hoverActions.enable#` is set.
|
/// `#rust-analyzer.hoverActions.enable#` is set.
|
||||||
hoverActions_run: bool = "true",
|
hoverActions_run: bool = "true",
|
||||||
|
@ -719,6 +722,7 @@ impl Config {
|
||||||
HoverConfig {
|
HoverConfig {
|
||||||
implementations: self.data.hoverActions_enable
|
implementations: self.data.hoverActions_enable
|
||||||
&& self.data.hoverActions_implementations,
|
&& self.data.hoverActions_implementations,
|
||||||
|
references: self.data.hoverActions_enable && self.data.hoverActions_references,
|
||||||
run: self.data.hoverActions_enable && self.data.hoverActions_run,
|
run: self.data.hoverActions_enable && self.data.hoverActions_run,
|
||||||
debug: self.data.hoverActions_enable && self.data.hoverActions_debug,
|
debug: self.data.hoverActions_enable && self.data.hoverActions_debug,
|
||||||
goto_type_def: self.data.hoverActions_enable && self.data.hoverActions_gotoTypeDef,
|
goto_type_def: self.data.hoverActions_enable && self.data.hoverActions_gotoTypeDef,
|
||||||
|
|
|
@ -1506,6 +1506,36 @@ fn show_impl_command_link(
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn show_ref_command_link(
|
||||||
|
snap: &GlobalStateSnapshot,
|
||||||
|
position: &FilePosition,
|
||||||
|
) -> Option<lsp_ext::CommandLinkGroup> {
|
||||||
|
if snap.config.hover().implementations {
|
||||||
|
if let Some(ref_search_res) = snap.analysis.find_all_refs(*position, None).unwrap_or(None) {
|
||||||
|
let uri = to_proto::url(snap, position.file_id);
|
||||||
|
let line_index = snap.file_line_index(position.file_id).ok()?;
|
||||||
|
let position = to_proto::position(&line_index, position.offset);
|
||||||
|
let locations: Vec<_> = ref_search_res
|
||||||
|
.references
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(|(file_id, ranges)| {
|
||||||
|
ranges.into_iter().filter_map(move |(range, _)| {
|
||||||
|
to_proto::location(snap, FileRange { file_id, range }).ok()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let title = to_proto::reference_title(locations.len());
|
||||||
|
let command = to_proto::command::show_references(title, &uri, position, locations);
|
||||||
|
|
||||||
|
return Some(lsp_ext::CommandLinkGroup {
|
||||||
|
commands: vec![to_command_link(command, "Go to references".into())],
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn runnable_action_links(
|
fn runnable_action_links(
|
||||||
snap: &GlobalStateSnapshot,
|
snap: &GlobalStateSnapshot,
|
||||||
runnable: Runnable,
|
runnable: Runnable,
|
||||||
|
@ -1566,6 +1596,7 @@ fn prepare_hover_actions(
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|it| match it {
|
.filter_map(|it| match it {
|
||||||
HoverAction::Implementation(position) => show_impl_command_link(snap, position),
|
HoverAction::Implementation(position) => show_impl_command_link(snap, position),
|
||||||
|
HoverAction::Reference(position) => show_ref_command_link(snap, position),
|
||||||
HoverAction::Runnable(r) => runnable_action_links(snap, r.clone()),
|
HoverAction::Runnable(r) => runnable_action_links(snap, r.clone()),
|
||||||
HoverAction::GoToType(targets) => goto_type_action_links(snap, targets),
|
HoverAction::GoToType(targets) => goto_type_action_links(snap, targets),
|
||||||
})
|
})
|
||||||
|
|
|
@ -228,6 +228,12 @@ Whether to show `Go to Type Definition` action. Only applies when
|
||||||
Whether to show `Implementations` action. Only applies when
|
Whether to show `Implementations` action. Only applies when
|
||||||
`#rust-analyzer.hoverActions.enable#` is set.
|
`#rust-analyzer.hoverActions.enable#` is set.
|
||||||
--
|
--
|
||||||
|
[[rust-analyzer.hoverActions.references]]rust-analyzer.hoverActions.references (default: `false`)::
|
||||||
|
+
|
||||||
|
--
|
||||||
|
Whether to show `References` action. Only applies when
|
||||||
|
`#rust-analyzer.hoverActions.enable#` is set.
|
||||||
|
--
|
||||||
[[rust-analyzer.hoverActions.run]]rust-analyzer.hoverActions.run (default: `true`)::
|
[[rust-analyzer.hoverActions.run]]rust-analyzer.hoverActions.run (default: `true`)::
|
||||||
+
|
+
|
||||||
--
|
--
|
||||||
|
|
|
@ -660,6 +660,11 @@
|
||||||
"default": true,
|
"default": true,
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"rust-analyzer.hoverActions.references": {
|
||||||
|
"markdownDescription": "Whether to show `References` action. Only applies when\n`#rust-analyzer.hoverActions.enable#` is set.",
|
||||||
|
"default": false,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"rust-analyzer.hoverActions.run": {
|
"rust-analyzer.hoverActions.run": {
|
||||||
"markdownDescription": "Whether to show `Run` action. Only applies when\n`#rust-analyzer.hoverActions.enable#` is set.",
|
"markdownDescription": "Whether to show `Run` action. Only applies when\n`#rust-analyzer.hoverActions.enable#` is set.",
|
||||||
"default": true,
|
"default": true,
|
||||||
|
|
|
@ -165,6 +165,7 @@ export class Config {
|
||||||
return {
|
return {
|
||||||
enable: this.get<boolean>("hoverActions.enable"),
|
enable: this.get<boolean>("hoverActions.enable"),
|
||||||
implementations: this.get<boolean>("hoverActions.implementations"),
|
implementations: this.get<boolean>("hoverActions.implementations"),
|
||||||
|
references: this.get<boolean>("hoverActions.references"),
|
||||||
run: this.get<boolean>("hoverActions.run"),
|
run: this.get<boolean>("hoverActions.run"),
|
||||||
debug: this.get<boolean>("hoverActions.debug"),
|
debug: this.get<boolean>("hoverActions.debug"),
|
||||||
gotoTypeDef: this.get<boolean>("hoverActions.gotoTypeDef"),
|
gotoTypeDef: this.get<boolean>("hoverActions.gotoTypeDef"),
|
||||||
|
|
Loading…
Reference in a new issue