aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide/src/display.rs37
-rw-r--r--crates/ra_ide/src/hover.rs62
2 files changed, 33 insertions, 66 deletions
diff --git a/crates/ra_ide/src/display.rs b/crates/ra_ide/src/display.rs
index eaeaaa2b4..c395057a7 100644
--- a/crates/ra_ide/src/display.rs
+++ b/crates/ra_ide/src/display.rs
@@ -6,6 +6,8 @@ mod navigation_target;
6mod structure; 6mod structure;
7mod short_label; 7mod short_label;
8 8
9use std::fmt::{Display, Write};
10
9use ra_syntax::{ 11use ra_syntax::{
10 ast::{self, AstNode, AttrsOwner, NameOwner, TypeParamsOwner}, 12 ast::{self, AstNode, AttrsOwner, NameOwner, TypeParamsOwner},
11 SyntaxKind::{ATTR, COMMENT}, 13 SyntaxKind::{ATTR, COMMENT},
@@ -67,24 +69,27 @@ pub(crate) fn macro_label(node: &ast::MacroCall) -> String {
67 format!("{}macro_rules! {}", vis, name) 69 format!("{}macro_rules! {}", vis, name)
68} 70}
69 71
70pub(crate) fn rust_code_markup<CODE: AsRef<str>>(val: CODE) -> String { 72pub(crate) fn rust_code_markup(code: &impl Display) -> String {
71 rust_code_markup_with_doc::<_, &str>(val, None, None) 73 rust_code_markup_with_doc(code, None, None)
72} 74}
73 75
74pub(crate) fn rust_code_markup_with_doc<CODE, DOC>( 76pub(crate) fn rust_code_markup_with_doc(
75 val: CODE, 77 code: &impl Display,
76 doc: Option<DOC>, 78 doc: Option<&str>,
77 mod_path: Option<String>, 79 mod_path: Option<&str>,
78) -> String 80) -> String {
79where 81 let mut markup = "```rust\n".to_owned();
80 CODE: AsRef<str>, 82
81 DOC: AsRef<str>, 83 if let Some(mod_path) = mod_path {
82{ 84 if !mod_path.is_empty() {
83 let mod_path = 85 write!(markup, "{}\n", mod_path).unwrap();
84 mod_path.filter(|path| !path.is_empty()).map(|path| path + "\n").unwrap_or_default(); 86 }
87 }
88 write!(markup, "{}\n```", code).unwrap();
89
85 if let Some(doc) = doc { 90 if let Some(doc) = doc {
86 format!("```rust\n{}{}\n```\n\n{}", mod_path, val.as_ref(), doc.as_ref()) 91 write!(markup, "\n\n{}", doc).unwrap();
87 } else {
88 format!("```rust\n{}{}\n```", mod_path, val.as_ref())
89 } 92 }
93
94 markup
90} 95}
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index 0bbba4855..3bdd61a2e 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -1,4 +1,5 @@
1//! FIXME: write short doc here 1//! Logic for computing info that is displayed when the user hovers over any
2//! source code items (e.g. function call, struct field, variable symbol...)
2 3
3use hir::{ 4use hir::{
4 Adt, AsAssocItem, AssocItemContainer, FieldSource, HasSource, HirDisplay, ModuleDef, 5 Adt, AsAssocItem, AssocItemContainer, FieldSource, HasSource, HirDisplay, ModuleDef,
@@ -24,35 +25,20 @@ use itertools::Itertools;
24use std::iter::once; 25use std::iter::once;
25 26
26/// Contains the results when hovering over an item 27/// Contains the results when hovering over an item
27#[derive(Debug, Clone)] 28#[derive(Debug, Default)]
28pub struct HoverResult { 29pub struct HoverResult {
29 results: Vec<String>, 30 results: Vec<String>,
30 exact: bool,
31}
32
33impl Default for HoverResult {
34 fn default() -> Self {
35 HoverResult::new()
36 }
37} 31}
38 32
39impl HoverResult { 33impl HoverResult {
40 pub fn new() -> HoverResult { 34 pub fn new() -> HoverResult {
41 HoverResult { 35 Self::default()
42 results: Vec::new(),
43 // We assume exact by default
44 exact: true,
45 }
46 } 36 }
47 37
48 pub fn extend(&mut self, item: Option<String>) { 38 pub fn extend(&mut self, item: Option<String>) {
49 self.results.extend(item); 39 self.results.extend(item);
50 } 40 }
51 41
52 pub fn is_exact(&self) -> bool {
53 self.exact
54 }
55
56 pub fn is_empty(&self) -> bool { 42 pub fn is_empty(&self) -> bool {
57 self.results.is_empty() 43 self.results.is_empty()
58 } 44 }
@@ -72,20 +58,7 @@ impl HoverResult {
72 /// Returns the results converted into markup 58 /// Returns the results converted into markup
73 /// for displaying in a UI 59 /// for displaying in a UI
74 pub fn to_markup(&self) -> String { 60 pub fn to_markup(&self) -> String {
75 let mut markup = if !self.exact { 61 self.results.join("\n\n---\n")
76 let mut msg = String::from("Failed to exactly resolve the symbol. This is probably because rust_analyzer does not yet support traits.");
77 if !self.results.is_empty() {
78 msg.push_str(" \nThese items were found instead:");
79 }
80 msg.push_str("\n\n---\n");
81 msg
82 } else {
83 String::new()
84 };
85
86 markup.push_str(&self.results.join("\n\n---\n"));
87
88 markup
89 } 62 }
90} 63}
91 64
@@ -94,10 +67,10 @@ fn hover_text(
94 desc: Option<String>, 67 desc: Option<String>,
95 mod_path: Option<String>, 68 mod_path: Option<String>,
96) -> Option<String> { 69) -> Option<String> {
97 match (desc, docs, mod_path) { 70 if let Some(desc) = desc {
98 (Some(desc), docs, mod_path) => Some(rust_code_markup_with_doc(desc, docs, mod_path)), 71 Some(rust_code_markup_with_doc(&desc, docs.as_deref(), mod_path.as_deref()))
99 (None, Some(docs), _) => Some(docs), 72 } else {
100 _ => None, 73 docs
101 } 74 }
102} 75}
103 76
@@ -133,7 +106,7 @@ fn determine_mod_path(db: &RootDatabase, def: &Definition) -> Option<String> {
133 .flatten() 106 .flatten()
134 .join("::") 107 .join("::")
135 }); 108 });
136 mod_path 109 mod_path // FIXME: replace dashes with underscores in crate display name
137} 110}
138 111
139fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option<String> { 112fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option<String> {
@@ -170,9 +143,7 @@ fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option<Strin
170 ModuleDef::TypeAlias(it) => from_def_source(db, it, mod_path), 143 ModuleDef::TypeAlias(it) => from_def_source(db, it, mod_path),
171 ModuleDef::BuiltinType(it) => Some(it.to_string()), 144 ModuleDef::BuiltinType(it) => Some(it.to_string()),
172 }, 145 },
173 Definition::Local(it) => { 146 Definition::Local(it) => Some(rust_code_markup(&it.ty(db).display_truncated(db, None))),
174 Some(rust_code_markup(it.ty(db).display_truncated(db, None).to_string()))
175 }
176 Definition::TypeParam(_) | Definition::SelfType(_) => { 147 Definition::TypeParam(_) | Definition::SelfType(_) => {
177 // FIXME: Hover for generic param 148 // FIXME: Hover for generic param
178 None 149 None
@@ -237,7 +208,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
237 } 208 }
238 }?; 209 }?;
239 210
240 res.extend(Some(rust_code_markup(ty.display_truncated(db, None).to_string()))); 211 res.extend(Some(rust_code_markup(&ty.display_truncated(db, None))));
241 let range = sema.original_range(&node).range; 212 let range = sema.original_range(&node).range;
242 Some(RangeInfo::new(range, res)) 213 Some(RangeInfo::new(range, res))
243} 214}
@@ -595,7 +566,6 @@ fn func(foo: i32) { if true { <|>foo; }; }
595 ); 566 );
596 let hover = analysis.hover(position).unwrap().unwrap(); 567 let hover = analysis.hover(position).unwrap().unwrap();
597 assert_eq!(trim_markup_opt(hover.info.first()), Some("wrapper::Thing\nfn new() -> Thing")); 568 assert_eq!(trim_markup_opt(hover.info.first()), Some("wrapper::Thing\nfn new() -> Thing"));
598 assert_eq!(hover.info.is_exact(), true);
599 } 569 }
600 570
601 #[test] 571 #[test]
@@ -618,7 +588,6 @@ fn func(foo: i32) { if true { <|>foo; }; }
618 ); 588 );
619 let hover = analysis.hover(position).unwrap().unwrap(); 589 let hover = analysis.hover(position).unwrap().unwrap();
620 assert_eq!(trim_markup_opt(hover.info.first()), Some("const C: u32")); 590 assert_eq!(trim_markup_opt(hover.info.first()), Some("const C: u32"));
621 assert_eq!(hover.info.is_exact(), true);
622 } 591 }
623 592
624 #[test] 593 #[test]
@@ -635,7 +604,6 @@ fn func(foo: i32) { if true { <|>foo; }; }
635 ); 604 );
636 let hover = analysis.hover(position).unwrap().unwrap(); 605 let hover = analysis.hover(position).unwrap().unwrap();
637 assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing")); 606 assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing"));
638 assert_eq!(hover.info.is_exact(), true);
639 607
640 /* FIXME: revive these tests 608 /* FIXME: revive these tests
641 let (analysis, position) = single_file_with_position( 609 let (analysis, position) = single_file_with_position(
@@ -651,7 +619,6 @@ fn func(foo: i32) { if true { <|>foo; }; }
651 619
652 let hover = analysis.hover(position).unwrap().unwrap(); 620 let hover = analysis.hover(position).unwrap().unwrap();
653 assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing")); 621 assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing"));
654 assert_eq!(hover.info.is_exact(), true);
655 622
656 let (analysis, position) = single_file_with_position( 623 let (analysis, position) = single_file_with_position(
657 " 624 "
@@ -665,7 +632,6 @@ fn func(foo: i32) { if true { <|>foo; }; }
665 ); 632 );
666 let hover = analysis.hover(position).unwrap().unwrap(); 633 let hover = analysis.hover(position).unwrap().unwrap();
667 assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing")); 634 assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing"));
668 assert_eq!(hover.info.is_exact(), true);
669 635
670 let (analysis, position) = single_file_with_position( 636 let (analysis, position) = single_file_with_position(
671 " 637 "
@@ -678,7 +644,6 @@ fn func(foo: i32) { if true { <|>foo; }; }
678 ); 644 );
679 let hover = analysis.hover(position).unwrap().unwrap(); 645 let hover = analysis.hover(position).unwrap().unwrap();
680 assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing")); 646 assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing"));
681 assert_eq!(hover.info.is_exact(), true);
682 */ 647 */
683 } 648 }
684 649
@@ -696,7 +661,6 @@ fn func(foo: i32) { if true { <|>foo; }; }
696 ); 661 );
697 let hover = analysis.hover(position).unwrap().unwrap(); 662 let hover = analysis.hover(position).unwrap().unwrap();
698 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); 663 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32"));
699 assert_eq!(hover.info.is_exact(), true);
700 } 664 }
701 665
702 #[test] 666 #[test]
@@ -714,7 +678,6 @@ fn func(foo: i32) { if true { <|>foo; }; }
714 ); 678 );
715 let hover = analysis.hover(position).unwrap().unwrap(); 679 let hover = analysis.hover(position).unwrap().unwrap();
716 assert_eq!(trim_markup_opt(hover.info.first()), Some("macro_rules! foo")); 680 assert_eq!(trim_markup_opt(hover.info.first()), Some("macro_rules! foo"));
717 assert_eq!(hover.info.is_exact(), true);
718 } 681 }
719 682
720 #[test] 683 #[test]
@@ -726,7 +689,6 @@ fn func(foo: i32) { if true { <|>foo; }; }
726 ); 689 );
727 let hover = analysis.hover(position).unwrap().unwrap(); 690 let hover = analysis.hover(position).unwrap().unwrap();
728 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); 691 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32"));
729 assert_eq!(hover.info.is_exact(), true);
730 } 692 }
731 693
732 #[test] 694 #[test]