diff options
Diffstat (limited to 'crates/ra_ide/src/syntax_highlighting')
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/html.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/injection.rs | 16 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/tags.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/tests.rs | 58 |
4 files changed, 61 insertions, 19 deletions
diff --git a/crates/ra_ide/src/syntax_highlighting/html.rs b/crates/ra_ide/src/syntax_highlighting/html.rs index 5bada6252..99b6b25ab 100644 --- a/crates/ra_ide/src/syntax_highlighting/html.rs +++ b/crates/ra_ide/src/syntax_highlighting/html.rs | |||
@@ -19,7 +19,7 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo | |||
19 | ) | 19 | ) |
20 | } | 20 | } |
21 | 21 | ||
22 | let ranges = highlight(db, file_id, None); | 22 | let ranges = highlight(db, file_id, None, false); |
23 | let text = parse.tree().syntax().to_string(); | 23 | let text = parse.tree().syntax().to_string(); |
24 | let mut prev_pos = TextSize::from(0); | 24 | let mut prev_pos = TextSize::from(0); |
25 | let mut buf = String::new(); | 25 | let mut buf = String::new(); |
@@ -84,6 +84,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
84 | .variable { color: #DCDCCC; } | 84 | .variable { color: #DCDCCC; } |
85 | .format_specifier { color: #CC696B; } | 85 | .format_specifier { color: #CC696B; } |
86 | .mutable { text-decoration: underline; } | 86 | .mutable { text-decoration: underline; } |
87 | .unresolved_reference { color: #FC5555; } | ||
88 | .escape_sequence { color: #94BFF3; } | ||
87 | 89 | ||
88 | .keyword { color: #F0DFAF; font-weight: bold; } | 90 | .keyword { color: #F0DFAF; font-weight: bold; } |
89 | .keyword.unsafe { color: #BC8383; font-weight: bold; } | 91 | .keyword.unsafe { color: #BC8383; font-weight: bold; } |
diff --git a/crates/ra_ide/src/syntax_highlighting/injection.rs b/crates/ra_ide/src/syntax_highlighting/injection.rs index 3575a0fc6..929a5cc5c 100644 --- a/crates/ra_ide/src/syntax_highlighting/injection.rs +++ b/crates/ra_ide/src/syntax_highlighting/injection.rs | |||
@@ -53,6 +53,10 @@ pub(super) fn highlight_injection( | |||
53 | /// Mapping from extracted documentation code to original code | 53 | /// Mapping from extracted documentation code to original code |
54 | type RangesMap = BTreeMap<TextSize, TextSize>; | 54 | type RangesMap = BTreeMap<TextSize, TextSize>; |
55 | 55 | ||
56 | const RUSTDOC_FENCE: &'static str = "```"; | ||
57 | const RUSTDOC_FENCE_TOKENS: &[&'static str] = | ||
58 | &["", "rust", "should_panic", "ignore", "no_run", "compile_fail", "edition2015", "edition2018"]; | ||
59 | |||
56 | /// Extracts Rust code from documentation comments as well as a mapping from | 60 | /// Extracts Rust code from documentation comments as well as a mapping from |
57 | /// the extracted source code back to the original source ranges. | 61 | /// the extracted source code back to the original source ranges. |
58 | /// Lastly, a vector of new comment highlight ranges (spanning only the | 62 | /// Lastly, a vector of new comment highlight ranges (spanning only the |
@@ -67,6 +71,7 @@ pub(super) fn extract_doc_comments( | |||
67 | // Mapping from extracted documentation code to original code | 71 | // Mapping from extracted documentation code to original code |
68 | let mut range_mapping: RangesMap = BTreeMap::new(); | 72 | let mut range_mapping: RangesMap = BTreeMap::new(); |
69 | let mut line_start = TextSize::try_from(prefix.len()).unwrap(); | 73 | let mut line_start = TextSize::try_from(prefix.len()).unwrap(); |
74 | let mut is_codeblock = false; | ||
70 | let mut is_doctest = false; | 75 | let mut is_doctest = false; |
71 | // Replace the original, line-spanning comment ranges by new, only comment-prefix | 76 | // Replace the original, line-spanning comment ranges by new, only comment-prefix |
72 | // spanning comment ranges. | 77 | // spanning comment ranges. |
@@ -76,8 +81,13 @@ pub(super) fn extract_doc_comments( | |||
76 | .filter_map(|el| el.into_token().and_then(ast::Comment::cast)) | 81 | .filter_map(|el| el.into_token().and_then(ast::Comment::cast)) |
77 | .filter(|comment| comment.kind().doc.is_some()) | 82 | .filter(|comment| comment.kind().doc.is_some()) |
78 | .filter(|comment| { | 83 | .filter(|comment| { |
79 | if comment.text().contains("```") { | 84 | if let Some(idx) = comment.text().find(RUSTDOC_FENCE) { |
80 | is_doctest = !is_doctest; | 85 | is_codeblock = !is_codeblock; |
86 | // Check whether code is rust by inspecting fence guards | ||
87 | let guards = &comment.text()[idx + RUSTDOC_FENCE.len()..]; | ||
88 | let is_rust = | ||
89 | guards.split(',').all(|sub| RUSTDOC_FENCE_TOKENS.contains(&sub.trim())); | ||
90 | is_doctest = is_codeblock && is_rust; | ||
81 | false | 91 | false |
82 | } else { | 92 | } else { |
83 | is_doctest | 93 | is_doctest |
@@ -137,7 +147,7 @@ pub(super) fn highlight_doc_comment( | |||
137 | let (analysis, tmp_file_id) = Analysis::from_single_file(text); | 147 | let (analysis, tmp_file_id) = Analysis::from_single_file(text); |
138 | 148 | ||
139 | stack.push(); | 149 | stack.push(); |
140 | for mut h in analysis.highlight(tmp_file_id).unwrap() { | 150 | for mut h in analysis.with_db(|db| super::highlight(db, tmp_file_id, None, true)).unwrap() { |
141 | // Determine start offset and end offset in case of multi-line ranges | 151 | // Determine start offset and end offset in case of multi-line ranges |
142 | let mut start_offset = None; | 152 | let mut start_offset = None; |
143 | let mut end_offset = None; | 153 | let mut end_offset = None; |
diff --git a/crates/ra_ide/src/syntax_highlighting/tags.rs b/crates/ra_ide/src/syntax_highlighting/tags.rs index 94f466966..400d22fb6 100644 --- a/crates/ra_ide/src/syntax_highlighting/tags.rs +++ b/crates/ra_ide/src/syntax_highlighting/tags.rs | |||
@@ -23,6 +23,7 @@ pub enum HighlightTag { | |||
23 | Constant, | 23 | Constant, |
24 | Enum, | 24 | Enum, |
25 | EnumVariant, | 25 | EnumVariant, |
26 | EscapeSequence, | ||
26 | Field, | 27 | Field, |
27 | FormatSpecifier, | 28 | FormatSpecifier, |
28 | Function, | 29 | Function, |
@@ -71,6 +72,7 @@ impl HighlightTag { | |||
71 | HighlightTag::Constant => "constant", | 72 | HighlightTag::Constant => "constant", |
72 | HighlightTag::Enum => "enum", | 73 | HighlightTag::Enum => "enum", |
73 | HighlightTag::EnumVariant => "enum_variant", | 74 | HighlightTag::EnumVariant => "enum_variant", |
75 | HighlightTag::EscapeSequence => "escape_sequence", | ||
74 | HighlightTag::Field => "field", | 76 | HighlightTag::Field => "field", |
75 | HighlightTag::FormatSpecifier => "format_specifier", | 77 | HighlightTag::FormatSpecifier => "format_specifier", |
76 | HighlightTag::Function => "function", | 78 | HighlightTag::Function => "function", |
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs index 021f8e7e2..b4d56a7a0 100644 --- a/crates/ra_ide/src/syntax_highlighting/tests.rs +++ b/crates/ra_ide/src/syntax_highlighting/tests.rs | |||
@@ -7,18 +7,6 @@ use crate::{ | |||
7 | FileRange, TextRange, | 7 | FileRange, TextRange, |
8 | }; | 8 | }; |
9 | 9 | ||
10 | /// Highlights the code given by the `ra_fixture` argument, renders the | ||
11 | /// result as HTML, and compares it with the HTML file given as `snapshot`. | ||
12 | /// Note that the `snapshot` file is overwritten by the rendered HTML. | ||
13 | fn check_highlighting(ra_fixture: &str, snapshot: &str, rainbow: bool) { | ||
14 | let (analysis, file_id) = single_file(ra_fixture); | ||
15 | let dst_file = project_dir().join(snapshot); | ||
16 | let actual_html = &analysis.highlight_as_html(file_id, rainbow).unwrap(); | ||
17 | let expected_html = &read_text(&dst_file); | ||
18 | fs::write(dst_file, &actual_html).unwrap(); | ||
19 | assert_eq_text!(expected_html, actual_html); | ||
20 | } | ||
21 | |||
22 | #[test] | 10 | #[test] |
23 | fn test_highlighting() { | 11 | fn test_highlighting() { |
24 | check_highlighting( | 12 | check_highlighting( |
@@ -55,6 +43,12 @@ def_fn! { | |||
55 | } | 43 | } |
56 | } | 44 | } |
57 | 45 | ||
46 | macro_rules! noop { | ||
47 | ($expr:expr) => { | ||
48 | $expr | ||
49 | } | ||
50 | } | ||
51 | |||
58 | // comment | 52 | // comment |
59 | fn main() { | 53 | fn main() { |
60 | println!("Hello, {}!", 92); | 54 | println!("Hello, {}!", 92); |
@@ -73,10 +67,14 @@ fn main() { | |||
73 | // Do nothing | 67 | // Do nothing |
74 | } | 68 | } |
75 | 69 | ||
70 | noop!(noop!(1)); | ||
71 | |||
76 | let mut x = 42; | 72 | let mut x = 42; |
77 | let y = &mut x; | 73 | let y = &mut x; |
78 | let z = &y; | 74 | let z = &y; |
79 | 75 | ||
76 | let Foo { x: z, y } = Foo { x: z, y }; | ||
77 | |||
80 | y; | 78 | y; |
81 | } | 79 | } |
82 | 80 | ||
@@ -248,6 +246,10 @@ fn main() { | |||
248 | 246 | ||
249 | println!(r"Hello, {}!", "world"); | 247 | println!(r"Hello, {}!", "world"); |
250 | 248 | ||
249 | // escape sequences | ||
250 | println!("Hello\nWorld"); | ||
251 | println!("\u{48}\x65\x6C\x6C\x6F World"); | ||
252 | |||
251 | println!("{\x41}", A = 92); | 253 | println!("{\x41}", A = 92); |
252 | println!("{ничоси}", ничоси = 92); | 254 | println!("{ничоси}", ничоси = 92); |
253 | }"# | 255 | }"# |
@@ -289,7 +291,13 @@ fn main() { | |||
289 | fn test_highlight_doctest() { | 291 | fn test_highlight_doctest() { |
290 | check_highlighting( | 292 | check_highlighting( |
291 | r#" | 293 | r#" |
294 | struct Foo { | ||
295 | bar: bool, | ||
296 | } | ||
297 | |||
292 | impl Foo { | 298 | impl Foo { |
299 | pub const bar: bool = true; | ||
300 | |||
293 | /// Constructs a new `Foo`. | 301 | /// Constructs a new `Foo`. |
294 | /// | 302 | /// |
295 | /// # Examples | 303 | /// # Examples |
@@ -299,7 +307,7 @@ impl Foo { | |||
299 | /// let mut foo: Foo = Foo::new(); | 307 | /// let mut foo: Foo = Foo::new(); |
300 | /// ``` | 308 | /// ``` |
301 | pub const fn new() -> Foo { | 309 | pub const fn new() -> Foo { |
302 | Foo { } | 310 | Foo { bar: true } |
303 | } | 311 | } |
304 | 312 | ||
305 | /// `bar` method on `Foo`. | 313 | /// `bar` method on `Foo`. |
@@ -307,11 +315,15 @@ impl Foo { | |||
307 | /// # Examples | 315 | /// # Examples |
308 | /// | 316 | /// |
309 | /// ``` | 317 | /// ``` |
318 | /// use x::y; | ||
319 | /// | ||
310 | /// let foo = Foo::new(); | 320 | /// let foo = Foo::new(); |
311 | /// | 321 | /// |
312 | /// // calls bar on foo | 322 | /// // calls bar on foo |
313 | /// assert!(foo.bar()); | 323 | /// assert!(foo.bar()); |
314 | /// | 324 | /// |
325 | /// let bar = foo.bar || Foo::bar; | ||
326 | /// | ||
315 | /// /* multi-line | 327 | /// /* multi-line |
316 | /// comment */ | 328 | /// comment */ |
317 | /// | 329 | /// |
@@ -321,9 +333,13 @@ impl Foo { | |||
321 | /// | 333 | /// |
322 | /// ``` | 334 | /// ``` |
323 | /// | 335 | /// |
324 | /// ``` | 336 | /// ```rust,no_run |
325 | /// let foobar = Foo::new().bar(); | 337 | /// let foobar = Foo::new().bar(); |
326 | /// ``` | 338 | /// ``` |
339 | /// | ||
340 | /// ```sh | ||
341 | /// echo 1 | ||
342 | /// ``` | ||
327 | pub fn foo(&self) -> bool { | 343 | pub fn foo(&self) -> bool { |
328 | true | 344 | true |
329 | } | 345 | } |
@@ -332,5 +348,17 @@ impl Foo { | |||
332 | .trim(), | 348 | .trim(), |
333 | "crates/ra_ide/src/snapshots/highlight_doctest.html", | 349 | "crates/ra_ide/src/snapshots/highlight_doctest.html", |
334 | false, | 350 | false, |
335 | ) | 351 | ); |
352 | } | ||
353 | |||
354 | /// Highlights the code given by the `ra_fixture` argument, renders the | ||
355 | /// result as HTML, and compares it with the HTML file given as `snapshot`. | ||
356 | /// Note that the `snapshot` file is overwritten by the rendered HTML. | ||
357 | fn check_highlighting(ra_fixture: &str, snapshot: &str, rainbow: bool) { | ||
358 | let (analysis, file_id) = single_file(ra_fixture); | ||
359 | let dst_file = project_dir().join(snapshot); | ||
360 | let actual_html = &analysis.highlight_as_html(file_id, rainbow).unwrap(); | ||
361 | let expected_html = &read_text(&dst_file); | ||
362 | fs::write(dst_file, &actual_html).unwrap(); | ||
363 | assert_eq_text!(expected_html, actual_html); | ||
336 | } | 364 | } |