aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/hover.rs
diff options
context:
space:
mode:
authorVille Penttinen <[email protected]>2019-02-26 16:55:08 +0000
committerVille Penttinen <[email protected]>2019-02-26 16:55:08 +0000
commit3ec25841488f9d4325ec25d737c488c18419787c (patch)
tree8d2b5fdb93baf057c8303162b9fe2901b11da590 /crates/ra_ide_api/src/hover.rs
parent5e00a398f77247814a90a68ca351304381b8e82f (diff)
Add support for showing fn signature when hovering
Diffstat (limited to 'crates/ra_ide_api/src/hover.rs')
-rw-r--r--crates/ra_ide_api/src/hover.rs46
1 files changed, 43 insertions, 3 deletions
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs
index 364bf9f74..729f435d3 100644
--- a/crates/ra_ide_api/src/hover.rs
+++ b/crates/ra_ide_api/src/hover.rs
@@ -1,6 +1,6 @@
1use ra_db::SourceDatabase; 1use ra_db::SourceDatabase;
2use ra_syntax::{ 2use ra_syntax::{
3 AstNode, SyntaxNode, TreeArc, ast, 3 AstNode, SyntaxNode, TreeArc, ast::{self, NameOwner, VisibilityOwner, TypeParamsOwner},
4 algo::{find_covering_node, find_node_at_offset, find_leaf_at_offset, visit::{visitor, Visitor}}, 4 algo::{find_covering_node, find_node_at_offset, find_leaf_at_offset, visit::{visitor, Visitor}},
5}; 5};
6 6
@@ -118,9 +118,49 @@ impl NavigationTarget {
118 // TODO: After type inference is done, add type information to improve the output 118 // TODO: After type inference is done, add type information to improve the output
119 let node = self.node(db)?; 119 let node = self.node(db)?;
120 120
121 // FIXME: This is copied from `structure.rs` and should probably
122 // be moved somewhere common
123 fn collapse_ws(node: &SyntaxNode, output: &mut String) {
124 let mut can_insert_ws = false;
125 for line in node.text().chunks().flat_map(|chunk| chunk.lines()) {
126 let line = line.trim();
127 if line.is_empty() {
128 if can_insert_ws {
129 output.push_str(" ");
130 can_insert_ws = false;
131 }
132 } else {
133 output.push_str(line);
134 can_insert_ws = true;
135 }
136 }
137 }
138
139 fn visit_fn(node: &ast::FnDef) -> Option<String> {
140 let mut detail =
141 node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default();
142
143 detail.push_str("fn ");
144
145 node.name()?.syntax().text().push_to(&mut detail);
146
147 if let Some(type_param_list) = node.type_param_list() {
148 collapse_ws(type_param_list.syntax(), &mut detail);
149 }
150 if let Some(param_list) = node.param_list() {
151 collapse_ws(param_list.syntax(), &mut detail);
152 }
153 if let Some(ret_type) = node.ret_type() {
154 detail.push_str(" ");
155 collapse_ws(ret_type.syntax(), &mut detail);
156 }
157
158 Some(detail)
159 }
160
121 fn visit_node<T>(node: &T, label: &str) -> Option<String> 161 fn visit_node<T>(node: &T, label: &str) -> Option<String>
122 where 162 where
123 T: ast::NameOwner + ast::VisibilityOwner, 163 T: NameOwner + VisibilityOwner,
124 { 164 {
125 let mut string = 165 let mut string =
126 node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default(); 166 node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default();
@@ -130,7 +170,7 @@ impl NavigationTarget {
130 } 170 }
131 171
132 visitor() 172 visitor()
133 .visit(|node: &ast::FnDef| visit_node(node, "fn ")) 173 .visit(visit_fn)
134 .visit(|node: &ast::StructDef| visit_node(node, "struct ")) 174 .visit(|node: &ast::StructDef| visit_node(node, "struct "))
135 .visit(|node: &ast::EnumDef| visit_node(node, "enum ")) 175 .visit(|node: &ast::EnumDef| visit_node(node, "enum "))
136 .visit(|node: &ast::TraitDef| visit_node(node, "trait ")) 176 .visit(|node: &ast::TraitDef| visit_node(node, "trait "))