aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-03-17 17:59:54 +0000
committerLukas Wirth <[email protected]>2021-03-17 18:12:28 +0000
commit37964f9fef5e07684f4ff68142908f6266419faa (patch)
treeae3bcf85fb3a3d215f0d75a5cc064fd628c61457 /crates/ide/src
parentedf11480ceae1ef77d7084604011c0ef6f692c72 (diff)
Inject highlight into block doc comments
Diffstat (limited to 'crates/ide/src')
-rw-r--r--crates/ide/src/syntax_highlighting/inject.rs62
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html20
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs18
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
3use std::mem;
4
3use either::Either; 5use either::Either;
4use hir::{HasAttrs, Semantics}; 6use hir::{HasAttrs, Semantics};
5use ide_db::call_info::ActiveParameter; 7use 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">/**
127It 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/// ```
559pub fn mix_and_match() {} 559pub fn mix_and_match() {}
560
561/**
562It is beyond me why you'd use these when you got ///
563```rust
564let _ = example(&[1, 2, 3]);
565```
566 */
567pub fn block_comments() {}
568
569/**
570 Really, I don't get it
571 ```rust
572 let _ = example(&[1, 2, 3]);
573 ```
574*/
575pub 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"],