diff options
Diffstat (limited to 'crates/ide/src/syntax_highlighting/highlights.rs')
-rw-r--r-- | crates/ide/src/syntax_highlighting/highlights.rs | 61 |
1 files changed, 26 insertions, 35 deletions
diff --git a/crates/ide/src/syntax_highlighting/highlights.rs b/crates/ide/src/syntax_highlighting/highlights.rs index 3e733c87c..11c11ed28 100644 --- a/crates/ide/src/syntax_highlighting/highlights.rs +++ b/crates/ide/src/syntax_highlighting/highlights.rs | |||
@@ -4,33 +4,29 @@ use std::{cmp::Ordering, iter}; | |||
4 | use stdx::equal_range_by; | 4 | use stdx::equal_range_by; |
5 | use syntax::TextRange; | 5 | use syntax::TextRange; |
6 | 6 | ||
7 | use crate::{HighlightTag, HighlightedRange}; | 7 | use crate::{HlRange, HlTag}; |
8 | 8 | ||
9 | pub(super) struct Highlights { | 9 | pub(super) struct Highlights { |
10 | root: Node, | 10 | root: Node, |
11 | } | 11 | } |
12 | 12 | ||
13 | struct Node { | 13 | struct Node { |
14 | highlighted_range: HighlightedRange, | 14 | hl_range: HlRange, |
15 | nested: Vec<Node>, | 15 | nested: Vec<Node>, |
16 | } | 16 | } |
17 | 17 | ||
18 | impl Highlights { | 18 | impl Highlights { |
19 | pub(super) fn new(range: TextRange) -> Highlights { | 19 | pub(super) fn new(range: TextRange) -> Highlights { |
20 | Highlights { | 20 | Highlights { |
21 | root: Node::new(HighlightedRange { | 21 | root: Node::new(HlRange { range, highlight: HlTag::None.into(), binding_hash: None }), |
22 | range, | ||
23 | highlight: HighlightTag::Dummy.into(), | ||
24 | binding_hash: None, | ||
25 | }), | ||
26 | } | 22 | } |
27 | } | 23 | } |
28 | 24 | ||
29 | pub(super) fn add(&mut self, highlighted_range: HighlightedRange) { | 25 | pub(super) fn add(&mut self, hl_range: HlRange) { |
30 | self.root.add(highlighted_range); | 26 | self.root.add(hl_range); |
31 | } | 27 | } |
32 | 28 | ||
33 | pub(super) fn to_vec(self) -> Vec<HighlightedRange> { | 29 | pub(super) fn to_vec(self) -> Vec<HlRange> { |
34 | let mut res = Vec::new(); | 30 | let mut res = Vec::new(); |
35 | self.root.flatten(&mut res); | 31 | self.root.flatten(&mut res); |
36 | res | 32 | res |
@@ -38,59 +34,54 @@ impl Highlights { | |||
38 | } | 34 | } |
39 | 35 | ||
40 | impl Node { | 36 | impl Node { |
41 | fn new(highlighted_range: HighlightedRange) -> Node { | 37 | fn new(hl_range: HlRange) -> Node { |
42 | Node { highlighted_range, nested: Vec::new() } | 38 | Node { hl_range, nested: Vec::new() } |
43 | } | 39 | } |
44 | 40 | ||
45 | fn add(&mut self, highlighted_range: HighlightedRange) { | 41 | fn add(&mut self, hl_range: HlRange) { |
46 | assert!(self.highlighted_range.range.contains_range(highlighted_range.range)); | 42 | assert!(self.hl_range.range.contains_range(hl_range.range)); |
47 | 43 | ||
48 | // Fast path | 44 | // Fast path |
49 | if let Some(last) = self.nested.last_mut() { | 45 | if let Some(last) = self.nested.last_mut() { |
50 | if last.highlighted_range.range.contains_range(highlighted_range.range) { | 46 | if last.hl_range.range.contains_range(hl_range.range) { |
51 | return last.add(highlighted_range); | 47 | return last.add(hl_range); |
52 | } | 48 | } |
53 | if last.highlighted_range.range.end() <= highlighted_range.range.start() { | 49 | if last.hl_range.range.end() <= hl_range.range.start() { |
54 | return self.nested.push(Node::new(highlighted_range)); | 50 | return self.nested.push(Node::new(hl_range)); |
55 | } | 51 | } |
56 | } | 52 | } |
57 | 53 | ||
58 | let (start, len) = equal_range_by(&self.nested, |n| { | 54 | let (start, len) = |
59 | ordering(n.highlighted_range.range, highlighted_range.range) | 55 | equal_range_by(&self.nested, |n| ordering(n.hl_range.range, hl_range.range)); |
60 | }); | ||
61 | 56 | ||
62 | if len == 1 | 57 | if len == 1 && self.nested[start].hl_range.range.contains_range(hl_range.range) { |
63 | && self.nested[start].highlighted_range.range.contains_range(highlighted_range.range) | 58 | return self.nested[start].add(hl_range); |
64 | { | ||
65 | return self.nested[start].add(highlighted_range); | ||
66 | } | 59 | } |
67 | 60 | ||
68 | let nested = self | 61 | let nested = self |
69 | .nested | 62 | .nested |
70 | .splice(start..start + len, iter::once(Node::new(highlighted_range))) | 63 | .splice(start..start + len, iter::once(Node::new(hl_range))) |
71 | .collect::<Vec<_>>(); | 64 | .collect::<Vec<_>>(); |
72 | self.nested[start].nested = nested; | 65 | self.nested[start].nested = nested; |
73 | } | 66 | } |
74 | 67 | ||
75 | fn flatten(&self, acc: &mut Vec<HighlightedRange>) { | 68 | fn flatten(&self, acc: &mut Vec<HlRange>) { |
76 | let mut start = self.highlighted_range.range.start(); | 69 | let mut start = self.hl_range.range.start(); |
77 | let mut nested = self.nested.iter(); | 70 | let mut nested = self.nested.iter(); |
78 | loop { | 71 | loop { |
79 | let next = nested.next(); | 72 | let next = nested.next(); |
80 | let end = next.map_or(self.highlighted_range.range.end(), |it| { | 73 | let end = next.map_or(self.hl_range.range.end(), |it| it.hl_range.range.start()); |
81 | it.highlighted_range.range.start() | ||
82 | }); | ||
83 | if start < end { | 74 | if start < end { |
84 | acc.push(HighlightedRange { | 75 | acc.push(HlRange { |
85 | range: TextRange::new(start, end), | 76 | range: TextRange::new(start, end), |
86 | highlight: self.highlighted_range.highlight, | 77 | highlight: self.hl_range.highlight, |
87 | binding_hash: self.highlighted_range.binding_hash, | 78 | binding_hash: self.hl_range.binding_hash, |
88 | }); | 79 | }); |
89 | } | 80 | } |
90 | start = match next { | 81 | start = match next { |
91 | Some(child) => { | 82 | Some(child) => { |
92 | child.flatten(acc); | 83 | child.flatten(acc); |
93 | child.highlighted_range.range.end() | 84 | child.hl_range.range.end() |
94 | } | 85 | } |
95 | None => break, | 86 | None => break, |
96 | } | 87 | } |