diff options
-rw-r--r-- | crates/ra_ide/src/display.rs | 37 | ||||
-rw-r--r-- | crates/ra_ide/src/hover.rs | 62 |
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; | |||
6 | mod structure; | 6 | mod structure; |
7 | mod short_label; | 7 | mod short_label; |
8 | 8 | ||
9 | use std::fmt::{Display, Write}; | ||
10 | |||
9 | use ra_syntax::{ | 11 | use 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 | ||
70 | pub(crate) fn rust_code_markup<CODE: AsRef<str>>(val: CODE) -> String { | 72 | pub(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 | ||
74 | pub(crate) fn rust_code_markup_with_doc<CODE, DOC>( | 76 | pub(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 { |
79 | where | 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 | ||
3 | use hir::{ | 4 | use hir::{ |
4 | Adt, AsAssocItem, AssocItemContainer, FieldSource, HasSource, HirDisplay, ModuleDef, | 5 | Adt, AsAssocItem, AssocItemContainer, FieldSource, HasSource, HirDisplay, ModuleDef, |
@@ -24,35 +25,20 @@ use itertools::Itertools; | |||
24 | use std::iter::once; | 25 | use 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)] |
28 | pub struct HoverResult { | 29 | pub struct HoverResult { |
29 | results: Vec<String>, | 30 | results: Vec<String>, |
30 | exact: bool, | ||
31 | } | ||
32 | |||
33 | impl Default for HoverResult { | ||
34 | fn default() -> Self { | ||
35 | HoverResult::new() | ||
36 | } | ||
37 | } | 31 | } |
38 | 32 | ||
39 | impl HoverResult { | 33 | impl 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 | ||
139 | fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option<String> { | 112 | fn 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] |