diff options
-rw-r--r-- | crates/ide/src/syntax_highlighting/inject.rs | 62 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html | 20 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/tests.rs | 18 |
3 files changed, 72 insertions, 28 deletions
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs index d57ce4027..7a4f2645f 100644 --- a/crates/ide/src/syntax_highlighting/inject.rs +++ b/crates/ide/src/syntax_highlighting/inject.rs | |||
@@ -1,5 +1,7 @@ | |||
1 | //! "Recursive" Syntax highlighting for code in doctests and fixtures. | 1 | //! "Recursive" Syntax highlighting for code in doctests and fixtures. |
2 | 2 | ||
3 | use std::mem; | ||
4 | |||
3 | use either::Either; | 5 | use either::Either; |
4 | use hir::{HasAttrs, Semantics}; | 6 | use hir::{HasAttrs, Semantics}; |
5 | use ide_db::call_info::ActiveParameter; | 7 | use ide_db::call_info::ActiveParameter; |
@@ -186,34 +188,44 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n | |||
186 | } | 188 | } |
187 | }; | 189 | }; |
188 | 190 | ||
189 | match line.find(RUSTDOC_FENCE) { | 191 | let mut pos = TextSize::from(prefix.len() as u32); |
190 | Some(idx) => { | 192 | let mut range_start = range.start(); |
191 | is_codeblock = !is_codeblock; | 193 | for line in line.split('\n') { |
192 | // Check whether code is rust by inspecting fence guards | 194 | let line_len = TextSize::from(line.len() as u32); |
193 | let guards = &line[idx + RUSTDOC_FENCE.len()..]; | 195 | let prev_range_start = { |
194 | let is_rust = | 196 | let next_range_start = range_start + line_len + TextSize::from(1); |
195 | guards.split(',').all(|sub| RUSTDOC_FENCE_TOKENS.contains(&sub.trim())); | 197 | mem::replace(&mut range_start, next_range_start) |
196 | is_doctest = is_codeblock && is_rust; | 198 | }; |
197 | continue; | 199 | // only first line has the prefix so take it away for future iterations |
200 | let mut pos = mem::take(&mut pos); | ||
201 | |||
202 | match line.find(RUSTDOC_FENCE) { | ||
203 | Some(idx) => { | ||
204 | is_codeblock = !is_codeblock; | ||
205 | // Check whether code is rust by inspecting fence guards | ||
206 | let guards = &line[idx + RUSTDOC_FENCE.len()..]; | ||
207 | let is_rust = | ||
208 | guards.split(',').all(|sub| RUSTDOC_FENCE_TOKENS.contains(&sub.trim())); | ||
209 | is_doctest = is_codeblock && is_rust; | ||
210 | continue; | ||
211 | } | ||
212 | None if !is_doctest => continue, | ||
213 | None => (), | ||
198 | } | 214 | } |
199 | None if !is_doctest => continue, | ||
200 | None => (), | ||
201 | } | ||
202 | |||
203 | let mut pos = TextSize::of(prefix); | ||
204 | // whitespace after comment is ignored | ||
205 | if let Some(ws) = line[pos.into()..].chars().next().filter(|c| c.is_whitespace()) { | ||
206 | pos += TextSize::of(ws); | ||
207 | } | ||
208 | // lines marked with `#` should be ignored in output, we skip the `#` char | ||
209 | if let Some(ws) = line[pos.into()..].chars().next().filter(|&c| c == '#') { | ||
210 | pos += TextSize::of(ws); | ||
211 | } | ||
212 | 215 | ||
213 | new_comments.push(TextRange::at(range.start(), pos)); | 216 | // whitespace after comment is ignored |
217 | if let Some(ws) = line[pos.into()..].chars().next().filter(|c| c.is_whitespace()) { | ||
218 | pos += TextSize::of(ws); | ||
219 | } | ||
220 | // lines marked with `#` should be ignored in output, we skip the `#` char | ||
221 | if line[pos.into()..].starts_with('#') { | ||
222 | pos += TextSize::of('#'); | ||
223 | } | ||
214 | 224 | ||
215 | inj.add(&line[pos.into()..], TextRange::new(range.start() + pos, range.end())); | 225 | new_comments.push(TextRange::at(prev_range_start, pos)); |
216 | inj.add_unmapped("\n"); | 226 | inj.add(&line[pos.into()..], TextRange::new(pos, line_len) + prev_range_start); |
227 | inj.add_unmapped("\n"); | ||
228 | } | ||
217 | } | 229 | } |
218 | inj.add_unmapped("\n}"); | 230 | inj.add_unmapped("\n}"); |
219 | 231 | ||
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html index 45817faf9..d792a23cf 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html | |||
@@ -81,7 +81,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
81 | <span class="comment documentation">/// </span><span class="comment injected"> comment */</span> | 81 | <span class="comment documentation">/// </span><span class="comment injected"> comment */</span> |
82 | <span class="comment documentation">///</span> | 82 | <span class="comment documentation">///</span> |
83 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">multi_line_string</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="string_literal injected">"Foo</span> | 83 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">multi_line_string</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="string_literal injected">"Foo</span> |
84 | <span class="comment documentation">/// </span><span class="string_literal injected"> bar</span> | 84 | <span class="comment documentation">/// </span><span class="string_literal injected"> bar</span><span class="escape_sequence injected">\n</span> |
85 | <span class="comment documentation">/// </span><span class="string_literal injected"> "</span><span class="semicolon injected">;</span> | 85 | <span class="comment documentation">/// </span><span class="string_literal injected"> "</span><span class="semicolon injected">;</span> |
86 | <span class="comment documentation">///</span> | 86 | <span class="comment documentation">///</span> |
87 | <span class="comment documentation">/// ```</span> | 87 | <span class="comment documentation">/// ```</span> |
@@ -121,4 +121,20 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
121 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">cfg_attr</span><span class="parenthesis attribute">(</span><span class="attribute attribute">not</span><span class="parenthesis attribute">(</span><span class="attribute attribute">feature </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"alloc"</span><span class="parenthesis attribute">)</span><span class="comma attribute">,</span><span class="attribute attribute"> doc </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"```ignore"</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span> | 121 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">cfg_attr</span><span class="parenthesis attribute">(</span><span class="attribute attribute">not</span><span class="parenthesis attribute">(</span><span class="attribute attribute">feature </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"alloc"</span><span class="parenthesis attribute">)</span><span class="comma attribute">,</span><span class="attribute attribute"> doc </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"```ignore"</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span> |
122 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="punctuation injected">_</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="function injected">example</span><span class="parenthesis injected">(</span><span class="operator injected">&</span><span class="none injected">alloc::</span><span class="macro injected">vec!</span><span class="bracket injected">[</span><span class="numeric_literal injected">1</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">2</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">3</span><span class="bracket injected">]</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span> | 122 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="punctuation injected">_</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="function injected">example</span><span class="parenthesis injected">(</span><span class="operator injected">&</span><span class="none injected">alloc::</span><span class="macro injected">vec!</span><span class="bracket injected">[</span><span class="numeric_literal injected">1</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">2</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">3</span><span class="bracket injected">]</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span> |
123 | <span class="comment documentation">/// ```</span> | 123 | <span class="comment documentation">/// ```</span> |
124 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration">mix_and_match</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span></code></pre> \ No newline at end of file | 124 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration">mix_and_match</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
125 | |||
126 | <span class="comment documentation">/** | ||
127 | It is beyond me why you'd use these when you got /// | ||
128 | ```rust | ||
129 | </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="punctuation injected">_</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="function injected">example</span><span class="parenthesis injected">(</span><span class="operator injected">&</span><span class="bracket injected">[</span><span class="numeric_literal injected">1</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">2</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">3</span><span class="bracket injected">]</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span><span class="comment documentation"> | ||
130 | ``` | ||
131 | */</span> | ||
132 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration">block_comments</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> | ||
133 | |||
134 | <span class="comment documentation">/** | ||
135 | Really, I don't get it | ||
136 | ```rust | ||
137 | </span><span class="comment documentation"> </span><span class="none injected"> </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="punctuation injected">_</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="function injected">example</span><span class="parenthesis injected">(</span><span class="operator injected">&</span><span class="bracket injected">[</span><span class="numeric_literal injected">1</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">2</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">3</span><span class="bracket injected">]</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span><span class="comment documentation"> | ||
138 | ``` | ||
139 | */</span> | ||
140 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration">block_comments2</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span></code></pre> \ No newline at end of file | ||
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index a5ef2d29b..cf0b86ad0 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs | |||
@@ -516,7 +516,7 @@ impl Foo { | |||
516 | /// comment */ | 516 | /// comment */ |
517 | /// | 517 | /// |
518 | /// let multi_line_string = "Foo | 518 | /// let multi_line_string = "Foo |
519 | /// bar | 519 | /// bar\n |
520 | /// "; | 520 | /// "; |
521 | /// | 521 | /// |
522 | /// ``` | 522 | /// ``` |
@@ -557,6 +557,22 @@ macro_rules! noop { | |||
557 | /// let _ = example(&alloc::vec![1, 2, 3]); | 557 | /// let _ = example(&alloc::vec![1, 2, 3]); |
558 | /// ``` | 558 | /// ``` |
559 | pub fn mix_and_match() {} | 559 | pub fn mix_and_match() {} |
560 | |||
561 | /** | ||
562 | It is beyond me why you'd use these when you got /// | ||
563 | ```rust | ||
564 | let _ = example(&[1, 2, 3]); | ||
565 | ``` | ||
566 | */ | ||
567 | pub fn block_comments() {} | ||
568 | |||
569 | /** | ||
570 | Really, I don't get it | ||
571 | ```rust | ||
572 | let _ = example(&[1, 2, 3]); | ||
573 | ``` | ||
574 | */ | ||
575 | pub fn block_comments2() {} | ||
560 | "# | 576 | "# |
561 | .trim(), | 577 | .trim(), |
562 | expect_file!["./test_data/highlight_doctest.html"], | 578 | expect_file!["./test_data/highlight_doctest.html"], |