Skip to content

Commit ec10835

Browse files
bors[bot]Veykril
andauthored
Merge #8069
8069: Inject highlight into block doc comments r=Veykril a=Veykril bors r+ Closes #6873 Co-authored-by: Lukas Wirth <[email protected]>
2 parents 4fa56e3 + 37964f9 commit ec10835

File tree

3 files changed

+72
-28
lines changed

3 files changed

+72
-28
lines changed

crates/ide/src/syntax_highlighting/inject.rs

+37-25
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! "Recursive" Syntax highlighting for code in doctests and fixtures.
22
3+
use std::mem;
4+
35
use either::Either;
46
use hir::{HasAttrs, Semantics};
57
use ide_db::call_info::ActiveParameter;
@@ -186,34 +188,44 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n
186188
}
187189
};
188190

189-
match line.find(RUSTDOC_FENCE) {
190-
Some(idx) => {
191-
is_codeblock = !is_codeblock;
192-
// Check whether code is rust by inspecting fence guards
193-
let guards = &line[idx + RUSTDOC_FENCE.len()..];
194-
let is_rust =
195-
guards.split(',').all(|sub| RUSTDOC_FENCE_TOKENS.contains(&sub.trim()));
196-
is_doctest = is_codeblock && is_rust;
197-
continue;
191+
let mut pos = TextSize::from(prefix.len() as u32);
192+
let mut range_start = range.start();
193+
for line in line.split('\n') {
194+
let line_len = TextSize::from(line.len() as u32);
195+
let prev_range_start = {
196+
let next_range_start = range_start + line_len + TextSize::from(1);
197+
mem::replace(&mut range_start, next_range_start)
198+
};
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 => (),
198214
}
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-
}
212215

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+
}
214224

215-
inj.add(&line[pos.into()..], TextRange::new(range.start() + pos, range.end()));
216-
inj.add_unmapped("\n");
225+
new_comments.push(TextRange::at(prev_range_start, pos));
226+
inj.add(&line[pos.into()..], TextRange::new(pos, line_len) + prev_range_start);
227+
inj.add_unmapped("\n");
228+
}
217229
}
218230
inj.add_unmapped("\n}");
219231

crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html

+18-2
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
<span class="comment documentation">/// </span><span class="comment injected"> comment */</span>
8282
<span class="comment documentation">///</span>
8383
<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>
8585
<span class="comment documentation">/// </span><span class="string_literal injected"> "</span><span class="semicolon injected">;</span>
8686
<span class="comment documentation">///</span>
8787
<span class="comment documentation">/// ```</span>
@@ -121,4 +121,20 @@
121121
<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>
122122
<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>
123123
<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>
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>

crates/ide/src/syntax_highlighting/tests.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ impl Foo {
516516
/// comment */
517517
///
518518
/// let multi_line_string = "Foo
519-
/// bar
519+
/// bar\n
520520
/// ";
521521
///
522522
/// ```
@@ -557,6 +557,22 @@ macro_rules! noop {
557557
/// let _ = example(&alloc::vec![1, 2, 3]);
558558
/// ```
559559
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() {}
560576
"#
561577
.trim(),
562578
expect_file!["./test_data/highlight_doctest.html"],

0 commit comments

Comments
 (0)