aboutsummaryrefslogtreecommitdiff
path: root/crates/ide
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-01-07 15:21:00 +0000
committerAleksey Kladov <[email protected]>2021-01-07 16:11:27 +0000
commitf459375f4873d601b6a0e2c3c5d29be569b3e067 (patch)
tree97bceccdbcfa1a5f5b932c16786e7339b4ff39da /crates/ide
parent7967ce85cfc5fc2b1996425b44f2a45d0841c8ff (diff)
Better fixture highlight
Diffstat (limited to 'crates/ide')
-rw-r--r--crates/ide/src/join_lines.rs12
-rw-r--r--crates/ide/src/syntax_highlighting/injection.rs56
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/injection.html48
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs19
4 files changed, 125 insertions, 10 deletions
diff --git a/crates/ide/src/join_lines.rs b/crates/ide/src/join_lines.rs
index 296893d2f..05380f2a1 100644
--- a/crates/ide/src/join_lines.rs
+++ b/crates/ide/src/join_lines.rs
@@ -198,8 +198,8 @@ mod tests {
198 198
199 use super::*; 199 use super::*;
200 200
201 fn check_join_lines(before: &str, after: &str) { 201 fn check_join_lines(ra_fixture_before: &str, ra_fixture_after: &str) {
202 let (before_cursor_pos, before) = extract_offset(before); 202 let (before_cursor_pos, before) = extract_offset(ra_fixture_before);
203 let file = SourceFile::parse(&before).ok().unwrap(); 203 let file = SourceFile::parse(&before).ok().unwrap();
204 204
205 let range = TextRange::empty(before_cursor_pos); 205 let range = TextRange::empty(before_cursor_pos);
@@ -214,7 +214,7 @@ mod tests {
214 .apply_to_offset(before_cursor_pos) 214 .apply_to_offset(before_cursor_pos)
215 .expect("cursor position is affected by the edit"); 215 .expect("cursor position is affected by the edit");
216 let actual = add_cursor(&actual, actual_cursor_pos); 216 let actual = add_cursor(&actual, actual_cursor_pos);
217 assert_eq_text!(after, &actual); 217 assert_eq_text!(ra_fixture_after, &actual);
218 } 218 }
219 219
220 #[test] 220 #[test]
@@ -604,8 +604,8 @@ fn foo() {
604 ); 604 );
605 } 605 }
606 606
607 fn check_join_lines_sel(before: &str, after: &str) { 607 fn check_join_lines_sel(ra_fixture_before: &str, ra_fixture_after: &str) {
608 let (sel, before) = extract_range(before); 608 let (sel, before) = extract_range(ra_fixture_before);
609 let parse = SourceFile::parse(&before); 609 let parse = SourceFile::parse(&before);
610 let result = join_lines(&parse.tree(), sel); 610 let result = join_lines(&parse.tree(), sel);
611 let actual = { 611 let actual = {
@@ -613,7 +613,7 @@ fn foo() {
613 result.apply(&mut actual); 613 result.apply(&mut actual);
614 actual 614 actual
615 }; 615 };
616 assert_eq_text!(after, &actual); 616 assert_eq_text!(ra_fixture_after, &actual);
617 } 617 }
618 618
619 #[test] 619 #[test]
diff --git a/crates/ide/src/syntax_highlighting/injection.rs b/crates/ide/src/syntax_highlighting/injection.rs
index 6cbd683c6..d6be9708d 100644
--- a/crates/ide/src/syntax_highlighting/injection.rs
+++ b/crates/ide/src/syntax_highlighting/injection.rs
@@ -22,7 +22,8 @@ pub(super) fn highlight_injection(
22 return None; 22 return None;
23 } 23 }
24 let value = literal.value()?; 24 let value = literal.value()?;
25 let (analysis, tmp_file_id) = Analysis::from_single_file(value.into_owned()); 25 let marker_info = MarkerInfo::new(&*value);
26 let (analysis, tmp_file_id) = Analysis::from_single_file(marker_info.cleaned_text.clone());
26 27
27 if let Some(range) = literal.open_quote_text_range() { 28 if let Some(range) = literal.open_quote_text_range() {
28 acc.add(HighlightedRange { 29 acc.add(HighlightedRange {
@@ -33,9 +34,10 @@ pub(super) fn highlight_injection(
33 } 34 }
34 35
35 for mut h in analysis.highlight(tmp_file_id).unwrap() { 36 for mut h in analysis.highlight(tmp_file_id).unwrap() {
36 if let Some(r) = literal.map_range_up(h.range) { 37 let range = marker_info.map_range_up(h.range);
37 h.range = r; 38 if let Some(range) = literal.map_range_up(range) {
38 acc.add(h) 39 h.range = range;
40 acc.add(h);
39 } 41 }
40 } 42 }
41 43
@@ -50,6 +52,52 @@ pub(super) fn highlight_injection(
50 Some(()) 52 Some(())
51} 53}
52 54
55/// Data to remove `$0` from string and map ranges
56#[derive(Default, Debug)]
57struct MarkerInfo {
58 cleaned_text: String,
59 markers: Vec<TextRange>,
60}
61
62impl MarkerInfo {
63 fn new(mut text: &str) -> Self {
64 let marker = "$0";
65
66 let mut res = MarkerInfo::default();
67 let mut offset: TextSize = 0.into();
68 while !text.is_empty() {
69 let idx = text.find(marker).unwrap_or(text.len());
70 let (chunk, next) = text.split_at(idx);
71 text = next;
72 res.cleaned_text.push_str(chunk);
73 offset += TextSize::of(chunk);
74
75 if let Some(next) = text.strip_prefix(marker) {
76 text = next;
77
78 let marker_len = TextSize::of(marker);
79 res.markers.push(TextRange::at(offset, marker_len));
80 offset += marker_len;
81 }
82 }
83 res
84 }
85 fn map_range_up(&self, range: TextRange) -> TextRange {
86 TextRange::new(
87 self.map_offset_up(range.start(), true),
88 self.map_offset_up(range.end(), false),
89 )
90 }
91 fn map_offset_up(&self, mut offset: TextSize, start: bool) -> TextSize {
92 for r in &self.markers {
93 if r.start() < offset || (start && r.start() == offset) {
94 offset += r.len()
95 }
96 }
97 offset
98 }
99}
100
53/// Mapping from extracted documentation code to original code 101/// Mapping from extracted documentation code to original code
54type RangesMap = BTreeMap<TextSize, TextSize>; 102type RangesMap = BTreeMap<TextSize, TextSize>;
55 103
diff --git a/crates/ide/src/syntax_highlighting/test_data/injection.html b/crates/ide/src/syntax_highlighting/test_data/injection.html
new file mode 100644
index 000000000..a54d303b4
--- /dev/null
+++ b/crates/ide/src/syntax_highlighting/test_data/injection.html
@@ -0,0 +1,48 @@
1
2<style>
3body { margin: 0; }
4pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
5
6.lifetime { color: #DFAF8F; font-style: italic; }
7.label { color: #DFAF8F; font-style: italic; }
8.comment { color: #7F9F7F; }
9.documentation { color: #629755; }
10.injected { opacity: 0.65 ; }
11.struct, .enum { color: #7CB8BB; }
12.enum_variant { color: #BDE0F3; }
13.string_literal { color: #CC9393; }
14.field { color: #94BFF3; }
15.function { color: #93E0E3; }
16.function.unsafe { color: #BC8383; }
17.operator.unsafe { color: #BC8383; }
18.parameter { color: #94BFF3; }
19.text { color: #DCDCCC; }
20.type { color: #7CB8BB; }
21.builtin_type { color: #8CD0D3; }
22.type_param { color: #DFAF8F; }
23.attribute { color: #94BFF3; }
24.numeric_literal { color: #BFEBBF; }
25.bool_literal { color: #BFE6EB; }
26.macro { color: #94BFF3; }
27.module { color: #AFD8AF; }
28.value_param { color: #DCDCCC; }
29.variable { color: #DCDCCC; }
30.format_specifier { color: #CC696B; }
31.mutable { text-decoration: underline; }
32.escape_sequence { color: #94BFF3; }
33.keyword { color: #F0DFAF; font-weight: bold; }
34.keyword.unsafe { color: #BC8383; font-weight: bold; }
35.control { font-style: italic; }
36
37.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
38</style>
39<pre><code><span class="keyword">fn</span> <span class="function declaration">f</span><span class="punctuation">(</span><span class="value_param declaration">ra_fixture</span><span class="punctuation">:</span> <span class="operator">&</span><span class="builtin_type">str</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
40<span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span>
41 <span class="function">f</span><span class="punctuation">(</span><span class="string_literal">r"</span>
42<span class="keyword">fn</span> <span class="function declaration">foo</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span>
43 <span class="function">foo</span><span class="punctuation">(</span>$0<span class="punctuation">{</span>
44 <span class="numeric_literal">92</span>
45 <span class="punctuation">}</span>$0<span class="punctuation">)</span>
46<span class="punctuation">}</span><span class="string_literal">"</span><span class="punctuation">)</span><span class="punctuation">;</span>
47<span class="punctuation">}</span>
48 </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 30b5b648e..9e1a3974c 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -555,6 +555,25 @@ impl t for foo {
555 ) 555 )
556} 556}
557 557
558#[test]
559fn test_injection() {
560 check_highlighting(
561 r##"
562fn f(ra_fixture: &str) {}
563fn main() {
564 f(r"
565fn foo() {
566 foo(\$0{
567 92
568 }\$0)
569}");
570}
571 "##,
572 expect_file!["./test_data/injection.html"],
573 false,
574 );
575}
576
558/// Highlights the code given by the `ra_fixture` argument, renders the 577/// Highlights the code given by the `ra_fixture` argument, renders the
559/// result as HTML, and compares it with the HTML file given as `snapshot`. 578/// result as HTML, and compares it with the HTML file given as `snapshot`.
560/// Note that the `snapshot` file is overwritten by the rendered HTML. 579/// Note that the `snapshot` file is overwritten by the rendered HTML.