diff options
-rw-r--r-- | crates/ide/src/syntax_highlighting.rs | 2 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/injection.rs | 78 |
2 files changed, 28 insertions, 52 deletions
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 3ba91b3f5..ad456bc00 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs | |||
@@ -33,7 +33,7 @@ use crate::{ | |||
33 | 33 | ||
34 | pub(crate) use html::highlight_as_html; | 34 | pub(crate) use html::highlight_as_html; |
35 | 35 | ||
36 | #[derive(Debug, Clone)] | 36 | #[derive(Debug, Clone, Copy)] |
37 | pub struct HlRange { | 37 | pub struct HlRange { |
38 | pub range: TextRange, | 38 | pub range: TextRange, |
39 | pub highlight: Highlight, | 39 | pub highlight: Highlight, |
diff --git a/crates/ide/src/syntax_highlighting/injection.rs b/crates/ide/src/syntax_highlighting/injection.rs index 22d7f601a..de2180b04 100644 --- a/crates/ide/src/syntax_highlighting/injection.rs +++ b/crates/ide/src/syntax_highlighting/injection.rs | |||
@@ -21,74 +21,50 @@ pub(super) fn highlight_injection( | |||
21 | if !active_parameter.name.starts_with("ra_fixture") { | 21 | if !active_parameter.name.starts_with("ra_fixture") { |
22 | return None; | 22 | return None; |
23 | } | 23 | } |
24 | |||
25 | let value = literal.value()?; | 24 | let value = literal.value()?; |
26 | let marker_info = MarkerInfo::new(&*value); | ||
27 | let (analysis, tmp_file_id) = Analysis::from_single_file(marker_info.cleaned_text.clone()); | ||
28 | 25 | ||
29 | if let Some(range) = literal.open_quote_text_range() { | 26 | if let Some(range) = literal.open_quote_text_range() { |
30 | hl.add(HlRange { range, highlight: HlTag::StringLiteral.into(), binding_hash: None }) | 27 | hl.add(HlRange { range, highlight: HlTag::StringLiteral.into(), binding_hash: None }) |
31 | } | 28 | } |
32 | 29 | ||
33 | for mut hl_range in analysis.highlight(tmp_file_id).unwrap() { | 30 | let mut inj = Injector::default(); |
34 | let range = marker_info.map_range_up(hl_range.range); | ||
35 | if let Some(range) = literal.map_range_up(range) { | ||
36 | hl_range.range = range; | ||
37 | hl.add(hl_range); | ||
38 | } | ||
39 | } | ||
40 | |||
41 | if let Some(range) = literal.close_quote_text_range() { | ||
42 | hl.add(HlRange { range, highlight: HlTag::StringLiteral.into(), binding_hash: None }) | ||
43 | } | ||
44 | |||
45 | Some(()) | ||
46 | } | ||
47 | 31 | ||
48 | /// Data to remove `$0` from string and map ranges | 32 | let mut text = &*value; |
49 | #[derive(Default, Debug)] | 33 | let mut offset: TextSize = 0.into(); |
50 | struct MarkerInfo { | ||
51 | cleaned_text: String, | ||
52 | markers: Vec<TextRange>, | ||
53 | } | ||
54 | 34 | ||
55 | impl MarkerInfo { | 35 | while !text.is_empty() { |
56 | fn new(mut text: &str) -> Self { | ||
57 | let marker = "$0"; | 36 | let marker = "$0"; |
37 | let idx = text.find(marker).unwrap_or(text.len()); | ||
38 | let (chunk, next) = text.split_at(idx); | ||
39 | inj.add(chunk, TextRange::at(offset, TextSize::of(chunk))); | ||
58 | 40 | ||
59 | let mut res = MarkerInfo::default(); | 41 | text = next; |
60 | let mut offset: TextSize = 0.into(); | 42 | offset += TextSize::of(chunk); |
61 | while !text.is_empty() { | ||
62 | let idx = text.find(marker).unwrap_or(text.len()); | ||
63 | let (chunk, next) = text.split_at(idx); | ||
64 | text = next; | ||
65 | res.cleaned_text.push_str(chunk); | ||
66 | offset += TextSize::of(chunk); | ||
67 | 43 | ||
68 | if let Some(next) = text.strip_prefix(marker) { | 44 | if let Some(next) = text.strip_prefix(marker) { |
69 | text = next; | 45 | text = next; |
70 | 46 | ||
71 | let marker_len = TextSize::of(marker); | 47 | let marker_len = TextSize::of(marker); |
72 | res.markers.push(TextRange::at(offset, marker_len)); | 48 | offset += marker_len; |
73 | offset += marker_len; | ||
74 | } | ||
75 | } | 49 | } |
76 | res | ||
77 | } | 50 | } |
78 | fn map_range_up(&self, range: TextRange) -> TextRange { | 51 | |
79 | TextRange::new( | 52 | let (analysis, tmp_file_id) = Analysis::from_single_file(inj.text().to_string()); |
80 | self.map_offset_up(range.start(), true), | 53 | |
81 | self.map_offset_up(range.end(), false), | 54 | for mut hl_range in analysis.highlight(tmp_file_id).unwrap() { |
82 | ) | 55 | for range in inj.map_range_up(hl_range.range) { |
83 | } | 56 | if let Some(range) = literal.map_range_up(range) { |
84 | fn map_offset_up(&self, mut offset: TextSize, start: bool) -> TextSize { | 57 | hl_range.range = range; |
85 | for r in &self.markers { | 58 | hl.add(hl_range.clone()); |
86 | if r.start() < offset || (start && r.start() == offset) { | ||
87 | offset += r.len() | ||
88 | } | 59 | } |
89 | } | 60 | } |
90 | offset | ||
91 | } | 61 | } |
62 | |||
63 | if let Some(range) = literal.close_quote_text_range() { | ||
64 | hl.add(HlRange { range, highlight: HlTag::StringLiteral.into(), binding_hash: None }) | ||
65 | } | ||
66 | |||
67 | Some(()) | ||
92 | } | 68 | } |
93 | 69 | ||
94 | const RUSTDOC_FENCE: &'static str = "```"; | 70 | const RUSTDOC_FENCE: &'static str = "```"; |