diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_ide_api/src/hover.rs | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index a2d203b4f..4722206e2 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs | |||
@@ -107,7 +107,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
107 | leaf.ancestors().find(|n| ast::Expr::cast(*n).is_some() || ast::Pat::cast(*n).is_some()) | 107 | leaf.ancestors().find(|n| ast::Expr::cast(*n).is_some() || ast::Pat::cast(*n).is_some()) |
108 | })?; | 108 | })?; |
109 | let frange = FileRange { file_id: position.file_id, range: node.range() }; | 109 | let frange = FileRange { file_id: position.file_id, range: node.range() }; |
110 | res.extend(type_of(db, frange).map(Into::into)); | 110 | res.extend(type_of(db, frange).map(rust_code_markup)); |
111 | range = Some(node.range()); | 111 | range = Some(node.range()); |
112 | } | 112 | } |
113 | 113 | ||
@@ -142,12 +142,27 @@ pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> { | |||
142 | } | 142 | } |
143 | } | 143 | } |
144 | 144 | ||
145 | fn rust_code_markup<CODE: AsRef<str>>(val: CODE) -> String { | ||
146 | rust_code_markup_with_doc::<_, &str>(val, None) | ||
147 | } | ||
148 | |||
149 | fn rust_code_markup_with_doc<CODE, DOC>(val: CODE, doc: Option<DOC>) -> String | ||
150 | where | ||
151 | CODE: AsRef<str>, | ||
152 | DOC: AsRef<str>, | ||
153 | { | ||
154 | if let Some(doc) = doc { | ||
155 | format!("```rust\n{}\n```\n\n{}", val.as_ref(), doc.as_ref()) | ||
156 | } else { | ||
157 | format!("```rust\n{}\n```", val.as_ref()) | ||
158 | } | ||
159 | } | ||
160 | |||
145 | // FIXME: this should not really use navigation target. Rather, approximately | 161 | // FIXME: this should not really use navigation target. Rather, approximately |
146 | // resolved symbol should return a `DefId`. | 162 | // resolved symbol should return a `DefId`. |
147 | fn doc_text_for(db: &RootDatabase, nav: NavigationTarget) -> Option<String> { | 163 | fn doc_text_for(db: &RootDatabase, nav: NavigationTarget) -> Option<String> { |
148 | match (nav.description(db), nav.docs(db)) { | 164 | match (nav.description(db), nav.docs(db)) { |
149 | (Some(desc), Some(docs)) => Some("```rust\n".to_string() + &*desc + "\n```\n\n" + &*docs), | 165 | (Some(desc), docs) => Some(rust_code_markup_with_doc(desc, docs)), |
150 | (Some(desc), None) => Some("```rust\n".to_string() + &*desc + "\n```"), | ||
151 | (None, Some(docs)) => Some(docs), | 166 | (None, Some(docs)) => Some(docs), |
152 | _ => None, | 167 | _ => None, |
153 | } | 168 | } |
@@ -238,6 +253,10 @@ mod tests { | |||
238 | s.trim_start_matches("```rust\n").trim_end_matches("\n```") | 253 | s.trim_start_matches("```rust\n").trim_end_matches("\n```") |
239 | } | 254 | } |
240 | 255 | ||
256 | fn trim_markup_opt(s: Option<&str>) -> Option<&str> { | ||
257 | s.map(trim_markup) | ||
258 | } | ||
259 | |||
241 | fn check_hover_result(fixture: &str, expected: &[&str]) { | 260 | fn check_hover_result(fixture: &str, expected: &[&str]) { |
242 | let (analysis, position) = analysis_and_position(fixture); | 261 | let (analysis, position) = analysis_and_position(fixture); |
243 | let hover = analysis.hover(position).unwrap().unwrap(); | 262 | let hover = analysis.hover(position).unwrap().unwrap(); |
@@ -264,7 +283,7 @@ mod tests { | |||
264 | ); | 283 | ); |
265 | let hover = analysis.hover(position).unwrap().unwrap(); | 284 | let hover = analysis.hover(position).unwrap().unwrap(); |
266 | assert_eq!(hover.range, TextRange::from_to(95.into(), 100.into())); | 285 | assert_eq!(hover.range, TextRange::from_to(95.into(), 100.into())); |
267 | assert_eq!(hover.info.first(), Some("u32")); | 286 | assert_eq!(trim_markup_opt(hover.info.first()), Some("u32")); |
268 | } | 287 | } |
269 | 288 | ||
270 | #[test] | 289 | #[test] |
@@ -410,21 +429,21 @@ mod tests { | |||
410 | ); | 429 | ); |
411 | let hover = analysis.hover(position).unwrap().unwrap(); | 430 | let hover = analysis.hover(position).unwrap().unwrap(); |
412 | // not the nicest way to show it currently | 431 | // not the nicest way to show it currently |
413 | assert_eq!(hover.info.first(), Some("Some<i32>(T) -> Option<T>")); | 432 | assert_eq!(trim_markup_opt(hover.info.first()), Some("Some<i32>(T) -> Option<T>")); |
414 | } | 433 | } |
415 | 434 | ||
416 | #[test] | 435 | #[test] |
417 | fn hover_for_local_variable() { | 436 | fn hover_for_local_variable() { |
418 | let (analysis, position) = single_file_with_position("fn func(foo: i32) { fo<|>o; }"); | 437 | let (analysis, position) = single_file_with_position("fn func(foo: i32) { fo<|>o; }"); |
419 | let hover = analysis.hover(position).unwrap().unwrap(); | 438 | let hover = analysis.hover(position).unwrap().unwrap(); |
420 | assert_eq!(hover.info.first(), Some("i32")); | 439 | assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); |
421 | } | 440 | } |
422 | 441 | ||
423 | #[test] | 442 | #[test] |
424 | fn hover_for_local_variable_pat() { | 443 | fn hover_for_local_variable_pat() { |
425 | let (analysis, position) = single_file_with_position("fn func(fo<|>o: i32) {}"); | 444 | let (analysis, position) = single_file_with_position("fn func(fo<|>o: i32) {}"); |
426 | let hover = analysis.hover(position).unwrap().unwrap(); | 445 | let hover = analysis.hover(position).unwrap().unwrap(); |
427 | assert_eq!(hover.info.first(), Some("i32")); | 446 | assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); |
428 | } | 447 | } |
429 | 448 | ||
430 | #[test] | 449 | #[test] |
@@ -491,6 +510,6 @@ mod tests { | |||
491 | ", | 510 | ", |
492 | ); | 511 | ); |
493 | let hover = analysis.hover(position).unwrap().unwrap(); | 512 | let hover = analysis.hover(position).unwrap().unwrap(); |
494 | assert_eq!(hover.info.first(), Some("Thing")); | 513 | assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing")); |
495 | } | 514 | } |
496 | } | 515 | } |