diff options
author | flw <[email protected]> | 2020-09-26 06:02:09 +0100 |
---|---|---|
committer | flw <[email protected]> | 2020-09-29 12:47:18 +0100 |
commit | e73ee9dfa28e2c093cc79e0e8d729945c43f3c81 (patch) | |
tree | 633e533ce5aa3c10337bafc240e1f4911e4ecb65 /crates/ide/src/hover.rs | |
parent | 18c62c8a39d95ce3bb10ff5446bb589b1128a090 (diff) |
Add hover config `linksInHover` to suppress links
Diffstat (limited to 'crates/ide/src/hover.rs')
-rw-r--r-- | crates/ide/src/hover.rs | 113 |
1 files changed, 104 insertions, 9 deletions
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 37171cbef..bb9f12cd3 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -14,7 +14,7 @@ use test_utils::mark; | |||
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | display::{macro_label, ShortLabel, ToNav, TryToNav}, | 16 | display::{macro_label, ShortLabel, ToNav, TryToNav}, |
17 | link_rewrite::rewrite_links, | 17 | link_rewrite::{remove_links, rewrite_links}, |
18 | markup::Markup, | 18 | markup::Markup, |
19 | runnables::runnable, | 19 | runnables::runnable, |
20 | FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, | 20 | FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, |
@@ -26,17 +26,29 @@ pub struct HoverConfig { | |||
26 | pub run: bool, | 26 | pub run: bool, |
27 | pub debug: bool, | 27 | pub debug: bool, |
28 | pub goto_type_def: bool, | 28 | pub goto_type_def: bool, |
29 | pub links_in_hover: bool, | ||
29 | } | 30 | } |
30 | 31 | ||
31 | impl Default for HoverConfig { | 32 | impl Default for HoverConfig { |
32 | fn default() -> Self { | 33 | fn default() -> Self { |
33 | Self { implementations: true, run: true, debug: true, goto_type_def: true } | 34 | Self { |
35 | implementations: true, | ||
36 | run: true, | ||
37 | debug: true, | ||
38 | goto_type_def: true, | ||
39 | links_in_hover: true, | ||
40 | } | ||
34 | } | 41 | } |
35 | } | 42 | } |
36 | 43 | ||
37 | impl HoverConfig { | 44 | impl HoverConfig { |
38 | pub const NO_ACTIONS: Self = | 45 | pub const NO_ACTIONS: Self = Self { |
39 | Self { implementations: false, run: false, debug: false, goto_type_def: false }; | 46 | implementations: false, |
47 | run: false, | ||
48 | debug: false, | ||
49 | goto_type_def: false, | ||
50 | links_in_hover: true, | ||
51 | }; | ||
40 | 52 | ||
41 | pub fn any(&self) -> bool { | 53 | pub fn any(&self) -> bool { |
42 | self.implementations || self.runnable() || self.goto_type_def | 54 | self.implementations || self.runnable() || self.goto_type_def |
@@ -75,7 +87,11 @@ pub struct HoverResult { | |||
75 | // | 87 | // |
76 | // Shows additional information, like type of an expression or documentation for definition when "focusing" code. | 88 | // Shows additional information, like type of an expression or documentation for definition when "focusing" code. |
77 | // Focusing is usually hovering with a mouse, but can also be triggered with a shortcut. | 89 | // Focusing is usually hovering with a mouse, but can also be triggered with a shortcut. |
78 | pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> { | 90 | pub(crate) fn hover( |
91 | db: &RootDatabase, | ||
92 | position: FilePosition, | ||
93 | links_in_hover: bool, | ||
94 | ) -> Option<RangeInfo<HoverResult>> { | ||
79 | let sema = Semantics::new(db); | 95 | let sema = Semantics::new(db); |
80 | let file = sema.parse(position.file_id).syntax().clone(); | 96 | let file = sema.parse(position.file_id).syntax().clone(); |
81 | let token = pick_best(file.token_at_offset(position.offset))?; | 97 | let token = pick_best(file.token_at_offset(position.offset))?; |
@@ -93,7 +109,11 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
93 | }; | 109 | }; |
94 | if let Some(definition) = definition { | 110 | if let Some(definition) = definition { |
95 | if let Some(markup) = hover_for_definition(db, definition) { | 111 | if let Some(markup) = hover_for_definition(db, definition) { |
96 | let markup = rewrite_links(db, &markup.as_str(), &definition); | 112 | let markup = if links_in_hover { |
113 | rewrite_links(db, &markup.as_str(), &definition) | ||
114 | } else { | ||
115 | remove_links(&markup.as_str()) | ||
116 | }; | ||
97 | res.markup = Markup::from(markup); | 117 | res.markup = Markup::from(markup); |
98 | if let Some(action) = show_implementations_action(db, definition) { | 118 | if let Some(action) = show_implementations_action(db, definition) { |
99 | res.actions.push(action); | 119 | res.actions.push(action); |
@@ -363,12 +383,23 @@ mod tests { | |||
363 | 383 | ||
364 | fn check_hover_no_result(ra_fixture: &str) { | 384 | fn check_hover_no_result(ra_fixture: &str) { |
365 | let (analysis, position) = analysis_and_position(ra_fixture); | 385 | let (analysis, position) = analysis_and_position(ra_fixture); |
366 | assert!(analysis.hover(position).unwrap().is_none()); | 386 | assert!(analysis.hover(position, true).unwrap().is_none()); |
367 | } | 387 | } |
368 | 388 | ||
369 | fn check(ra_fixture: &str, expect: Expect) { | 389 | fn check(ra_fixture: &str, expect: Expect) { |
370 | let (analysis, position) = analysis_and_position(ra_fixture); | 390 | let (analysis, position) = analysis_and_position(ra_fixture); |
371 | let hover = analysis.hover(position).unwrap().unwrap(); | 391 | let hover = analysis.hover(position, true).unwrap().unwrap(); |
392 | |||
393 | let content = analysis.db.file_text(position.file_id); | ||
394 | let hovered_element = &content[hover.range]; | ||
395 | |||
396 | let actual = format!("*{}*\n{}\n", hovered_element, hover.info.markup); | ||
397 | expect.assert_eq(&actual) | ||
398 | } | ||
399 | |||
400 | fn check_hover_no_links(ra_fixture: &str, expect: Expect) { | ||
401 | let (analysis, position) = analysis_and_position(ra_fixture); | ||
402 | let hover = analysis.hover(position, false).unwrap().unwrap(); | ||
372 | 403 | ||
373 | let content = analysis.db.file_text(position.file_id); | 404 | let content = analysis.db.file_text(position.file_id); |
374 | let hovered_element = &content[hover.range]; | 405 | let hovered_element = &content[hover.range]; |
@@ -379,7 +410,7 @@ mod tests { | |||
379 | 410 | ||
380 | fn check_actions(ra_fixture: &str, expect: Expect) { | 411 | fn check_actions(ra_fixture: &str, expect: Expect) { |
381 | let (analysis, position) = analysis_and_position(ra_fixture); | 412 | let (analysis, position) = analysis_and_position(ra_fixture); |
382 | let hover = analysis.hover(position).unwrap().unwrap(); | 413 | let hover = analysis.hover(position, true).unwrap().unwrap(); |
383 | expect.assert_debug_eq(&hover.info.actions) | 414 | expect.assert_debug_eq(&hover.info.actions) |
384 | } | 415 | } |
385 | 416 | ||
@@ -1810,6 +1841,70 @@ struct S { | |||
1810 | } | 1841 | } |
1811 | 1842 | ||
1812 | #[test] | 1843 | #[test] |
1844 | fn test_hover_no_links() { | ||
1845 | check_hover_no_links( | ||
1846 | r#" | ||
1847 | /// Test cases: | ||
1848 | /// case 1. bare URL: https://www.example.com/ | ||
1849 | /// case 2. inline URL with title: [example](https://www.example.com/) | ||
1850 | /// case 3. code refrence: [`Result`] | ||
1851 | /// case 4. code refrence but miss footnote: [`String`] | ||
1852 | /// case 5. autolink: <http://www.example.com/> | ||
1853 | /// case 6. email address: <[email protected]> | ||
1854 | /// case 7. refrence: [example][example] | ||
1855 | /// case 8. collapsed link: [example][] | ||
1856 | /// case 9. shortcut link: [example] | ||
1857 | /// case 10. inline without URL: [example]() | ||
1858 | /// case 11. refrence: [foo][foo] | ||
1859 | /// case 12. refrence: [foo][bar] | ||
1860 | /// case 13. collapsed link: [foo][] | ||
1861 | /// case 14. shortcut link: [foo] | ||
1862 | /// case 15. inline without URL: [foo]() | ||
1863 | /// case 16. just escaped text: \[foo] | ||
1864 | /// case 17. inline link: [Foo](foo::Foo) | ||
1865 | /// | ||
1866 | /// [`Result`]: ../../std/result/enum.Result.html | ||
1867 | /// [^example]: https://www.example.com/ | ||
1868 | pub fn fo<|>o() {} | ||
1869 | "#, | ||
1870 | expect![[r#" | ||
1871 | *foo* | ||
1872 | |||
1873 | ```rust | ||
1874 | test | ||
1875 | ``` | ||
1876 | |||
1877 | ```rust | ||
1878 | pub fn foo() | ||
1879 | ``` | ||
1880 | |||
1881 | --- | ||
1882 | |||
1883 | Test cases: | ||
1884 | case 1. bare URL: https://www.example.com/ | ||
1885 | case 2. inline URL with title: [example](https://www.example.com/) | ||
1886 | case 3. code refrence: `Result` | ||
1887 | case 4. code refrence but miss footnote: `String` | ||
1888 | case 5. autolink: http://www.example.com/ | ||
1889 | case 6. email address: [email protected] | ||
1890 | case 7. refrence: example | ||
1891 | case 8. collapsed link: example | ||
1892 | case 9. shortcut link: example | ||
1893 | case 10. inline without URL: example | ||
1894 | case 11. refrence: foo | ||
1895 | case 12. refrence: foo | ||
1896 | case 13. collapsed link: foo | ||
1897 | case 14. shortcut link: foo | ||
1898 | case 15. inline without URL: foo | ||
1899 | case 16. just escaped text: \[foo] | ||
1900 | case 17. inline link: Foo | ||
1901 | |||
1902 | [^example]: https://www.example.com/ | ||
1903 | "#]], | ||
1904 | ); | ||
1905 | } | ||
1906 | |||
1907 | #[test] | ||
1813 | fn test_hover_macro_generated_struct_fn_doc_comment() { | 1908 | fn test_hover_macro_generated_struct_fn_doc_comment() { |
1814 | mark::check!(hover_macro_generated_struct_fn_doc_comment); | 1909 | mark::check!(hover_macro_generated_struct_fn_doc_comment); |
1815 | 1910 | ||