diff options
Diffstat (limited to 'crates/ra_ide/src/syntax_highlighting/injection.rs')
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/injection.rs | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/crates/ra_ide/src/syntax_highlighting/injection.rs b/crates/ra_ide/src/syntax_highlighting/injection.rs index 3575a0fc6..415f24a6d 100644 --- a/crates/ra_ide/src/syntax_highlighting/injection.rs +++ b/crates/ra_ide/src/syntax_highlighting/injection.rs | |||
@@ -7,7 +7,10 @@ use hir::Semantics; | |||
7 | use ra_syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize}; | 7 | use ra_syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize}; |
8 | use stdx::SepBy; | 8 | use stdx::SepBy; |
9 | 9 | ||
10 | use crate::{call_info::ActiveParameter, Analysis, HighlightTag, HighlightedRange, RootDatabase}; | 10 | use crate::{ |
11 | call_info::ActiveParameter, Analysis, HighlightModifier, HighlightTag, HighlightedRange, | ||
12 | RootDatabase, | ||
13 | }; | ||
11 | 14 | ||
12 | use super::HighlightedRangeStack; | 15 | use super::HighlightedRangeStack; |
13 | 16 | ||
@@ -53,6 +56,10 @@ pub(super) fn highlight_injection( | |||
53 | /// Mapping from extracted documentation code to original code | 56 | /// Mapping from extracted documentation code to original code |
54 | type RangesMap = BTreeMap<TextSize, TextSize>; | 57 | type RangesMap = BTreeMap<TextSize, TextSize>; |
55 | 58 | ||
59 | const RUSTDOC_FENCE: &'static str = "```"; | ||
60 | const RUSTDOC_FENCE_TOKENS: &[&'static str] = | ||
61 | &["", "rust", "should_panic", "ignore", "no_run", "compile_fail", "edition2015", "edition2018"]; | ||
62 | |||
56 | /// Extracts Rust code from documentation comments as well as a mapping from | 63 | /// Extracts Rust code from documentation comments as well as a mapping from |
57 | /// the extracted source code back to the original source ranges. | 64 | /// the extracted source code back to the original source ranges. |
58 | /// Lastly, a vector of new comment highlight ranges (spanning only the | 65 | /// Lastly, a vector of new comment highlight ranges (spanning only the |
@@ -67,6 +74,7 @@ pub(super) fn extract_doc_comments( | |||
67 | // Mapping from extracted documentation code to original code | 74 | // Mapping from extracted documentation code to original code |
68 | let mut range_mapping: RangesMap = BTreeMap::new(); | 75 | let mut range_mapping: RangesMap = BTreeMap::new(); |
69 | let mut line_start = TextSize::try_from(prefix.len()).unwrap(); | 76 | let mut line_start = TextSize::try_from(prefix.len()).unwrap(); |
77 | let mut is_codeblock = false; | ||
70 | let mut is_doctest = false; | 78 | let mut is_doctest = false; |
71 | // Replace the original, line-spanning comment ranges by new, only comment-prefix | 79 | // Replace the original, line-spanning comment ranges by new, only comment-prefix |
72 | // spanning comment ranges. | 80 | // spanning comment ranges. |
@@ -76,8 +84,13 @@ pub(super) fn extract_doc_comments( | |||
76 | .filter_map(|el| el.into_token().and_then(ast::Comment::cast)) | 84 | .filter_map(|el| el.into_token().and_then(ast::Comment::cast)) |
77 | .filter(|comment| comment.kind().doc.is_some()) | 85 | .filter(|comment| comment.kind().doc.is_some()) |
78 | .filter(|comment| { | 86 | .filter(|comment| { |
79 | if comment.text().contains("```") { | 87 | if let Some(idx) = comment.text().find(RUSTDOC_FENCE) { |
80 | is_doctest = !is_doctest; | 88 | is_codeblock = !is_codeblock; |
89 | // Check whether code is rust by inspecting fence guards | ||
90 | let guards = &comment.text()[idx + RUSTDOC_FENCE.len()..]; | ||
91 | let is_rust = | ||
92 | guards.split(',').all(|sub| RUSTDOC_FENCE_TOKENS.contains(&sub.trim())); | ||
93 | is_doctest = is_codeblock && is_rust; | ||
81 | false | 94 | false |
82 | } else { | 95 | } else { |
83 | is_doctest | 96 | is_doctest |
@@ -108,7 +121,7 @@ pub(super) fn extract_doc_comments( | |||
108 | range.start(), | 121 | range.start(), |
109 | range.start() + TextSize::try_from(pos).unwrap(), | 122 | range.start() + TextSize::try_from(pos).unwrap(), |
110 | ), | 123 | ), |
111 | highlight: HighlightTag::Comment.into(), | 124 | highlight: HighlightTag::Comment | HighlightModifier::Documentation, |
112 | binding_hash: None, | 125 | binding_hash: None, |
113 | }); | 126 | }); |
114 | line_start += range.len() - TextSize::try_from(pos).unwrap(); | 127 | line_start += range.len() - TextSize::try_from(pos).unwrap(); |
@@ -137,7 +150,7 @@ pub(super) fn highlight_doc_comment( | |||
137 | let (analysis, tmp_file_id) = Analysis::from_single_file(text); | 150 | let (analysis, tmp_file_id) = Analysis::from_single_file(text); |
138 | 151 | ||
139 | stack.push(); | 152 | stack.push(); |
140 | for mut h in analysis.highlight(tmp_file_id).unwrap() { | 153 | 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 | 154 | // Determine start offset and end offset in case of multi-line ranges |
142 | let mut start_offset = None; | 155 | let mut start_offset = None; |
143 | let mut end_offset = None; | 156 | let mut end_offset = None; |
@@ -154,6 +167,7 @@ pub(super) fn highlight_doc_comment( | |||
154 | h.range.start() + start_offset, | 167 | h.range.start() + start_offset, |
155 | h.range.end() + end_offset.unwrap_or(start_offset), | 168 | h.range.end() + end_offset.unwrap_or(start_offset), |
156 | ); | 169 | ); |
170 | |||
157 | stack.add(h); | 171 | stack.add(h); |
158 | } | 172 | } |
159 | } | 173 | } |