diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-05-21 19:05:58 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-05-21 19:05:58 +0100 |
commit | 59732df8d40dfadc6dcf5951265416576399712a (patch) | |
tree | 5accb5fce10496334b49ed5a823d321572b375b4 /crates/ra_text_edit/src | |
parent | ba6cf638fbf3d0a025e804f2d354d91abc8afd28 (diff) | |
parent | 5b5ebec440841ee98a0aa70b71a135d94f5ca077 (diff) |
Merge #4557
4557: Formalize JoinLines protocol extension r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_text_edit/src')
-rw-r--r-- | crates/ra_text_edit/src/lib.rs | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/crates/ra_text_edit/src/lib.rs b/crates/ra_text_edit/src/lib.rs index 199fd1096..25554f583 100644 --- a/crates/ra_text_edit/src/lib.rs +++ b/crates/ra_text_edit/src/lib.rs | |||
@@ -17,7 +17,7 @@ pub struct Indel { | |||
17 | pub delete: TextRange, | 17 | pub delete: TextRange, |
18 | } | 18 | } |
19 | 19 | ||
20 | #[derive(Debug, Clone)] | 20 | #[derive(Default, Debug, Clone)] |
21 | pub struct TextEdit { | 21 | pub struct TextEdit { |
22 | indels: Vec<Indel>, | 22 | indels: Vec<Indel>, |
23 | } | 23 | } |
@@ -64,14 +64,6 @@ impl TextEdit { | |||
64 | builder.finish() | 64 | builder.finish() |
65 | } | 65 | } |
66 | 66 | ||
67 | pub(crate) fn from_indels(mut indels: Vec<Indel>) -> TextEdit { | ||
68 | indels.sort_by_key(|a| (a.delete.start(), a.delete.end())); | ||
69 | for (a1, a2) in indels.iter().zip(indels.iter().skip(1)) { | ||
70 | assert!(a1.delete.end() <= a2.delete.start()) | ||
71 | } | ||
72 | TextEdit { indels } | ||
73 | } | ||
74 | |||
75 | pub fn len(&self) -> usize { | 67 | pub fn len(&self) -> usize { |
76 | self.indels.len() | 68 | self.indels.len() |
77 | } | 69 | } |
@@ -122,6 +114,17 @@ impl TextEdit { | |||
122 | *text = buf | 114 | *text = buf |
123 | } | 115 | } |
124 | 116 | ||
117 | pub fn union(&mut self, other: TextEdit) -> Result<(), TextEdit> { | ||
118 | // FIXME: can be done without allocating intermediate vector | ||
119 | let mut all = self.iter().chain(other.iter()).collect::<Vec<_>>(); | ||
120 | if !check_disjoint(&mut all) { | ||
121 | return Err(other); | ||
122 | } | ||
123 | self.indels.extend(other.indels); | ||
124 | assert!(check_disjoint(&mut self.indels)); | ||
125 | Ok(()) | ||
126 | } | ||
127 | |||
125 | pub fn apply_to_offset(&self, offset: TextSize) -> Option<TextSize> { | 128 | pub fn apply_to_offset(&self, offset: TextSize) -> Option<TextSize> { |
126 | let mut res = offset; | 129 | let mut res = offset; |
127 | for indel in self.indels.iter() { | 130 | for indel in self.indels.iter() { |
@@ -149,9 +152,19 @@ impl TextEditBuilder { | |||
149 | self.indels.push(Indel::insert(offset, text)) | 152 | self.indels.push(Indel::insert(offset, text)) |
150 | } | 153 | } |
151 | pub fn finish(self) -> TextEdit { | 154 | pub fn finish(self) -> TextEdit { |
152 | TextEdit::from_indels(self.indels) | 155 | let mut indels = self.indels; |
156 | assert!(check_disjoint(&mut indels)); | ||
157 | TextEdit { indels } | ||
153 | } | 158 | } |
154 | pub fn invalidates_offset(&self, offset: TextSize) -> bool { | 159 | pub fn invalidates_offset(&self, offset: TextSize) -> bool { |
155 | self.indels.iter().any(|indel| indel.delete.contains_inclusive(offset)) | 160 | self.indels.iter().any(|indel| indel.delete.contains_inclusive(offset)) |
156 | } | 161 | } |
157 | } | 162 | } |
163 | |||
164 | fn check_disjoint(indels: &mut [impl std::borrow::Borrow<Indel>]) -> bool { | ||
165 | indels.sort_by_key(|indel| (indel.borrow().delete.start(), indel.borrow().delete.end())); | ||
166 | indels | ||
167 | .iter() | ||
168 | .zip(indels.iter().skip(1)) | ||
169 | .all(|(l, r)| l.borrow().delete.end() <= r.borrow().delete.start()) | ||
170 | } | ||