aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernardo <[email protected]>2018-12-22 14:44:27 +0000
committerBernardo <[email protected]>2018-12-25 19:03:14 +0000
commit5c8525ce4ae8bb969f2ac263bf14adad1c835c03 (patch)
tree19df6e95432bbbc0e1c9c75b0867ffe3d378fa0a
parent36f2b1f3b9c36ace65852d971f998a090cf9b5d5 (diff)
column translation implemented but not quite working yet
-rw-r--r--crates/ra_editor/benches/translate_offset_with_edit_benchmark.rs4
-rw-r--r--crates/ra_editor/src/line_index.rs14
-rw-r--r--crates/ra_editor/src/line_index_utils.rs102
3 files changed, 70 insertions, 50 deletions
diff --git a/crates/ra_editor/benches/translate_offset_with_edit_benchmark.rs b/crates/ra_editor/benches/translate_offset_with_edit_benchmark.rs
index b345a91ae..89ed99823 100644
--- a/crates/ra_editor/benches/translate_offset_with_edit_benchmark.rs
+++ b/crates/ra_editor/benches/translate_offset_with_edit_benchmark.rs
@@ -72,10 +72,10 @@ fn compare_translates(c: &mut Criterion) {
72 }) 72 })
73 }); 73 });
74 74
75 let f2 = Fun::new("count_newlines", |b, _| { 75 let f2 = Fun::new("translate_offset_with_edit", |b, _| {
76 b.iter(|| { 76 b.iter(|| {
77 let d = &*DATA; 77 let d = &*DATA;
78 line_index_utils::count_newlines(d.offset, &d.line_index, &d.edits); 78 line_index_utils::translate_offset_with_edit(&d.line_index, d.offset, &d.edits);
79 }) 79 })
80 }); 80 });
81 81
diff --git a/crates/ra_editor/src/line_index.rs b/crates/ra_editor/src/line_index.rs
index c29e2e49a..6dbabd97e 100644
--- a/crates/ra_editor/src/line_index.rs
+++ b/crates/ra_editor/src/line_index.rs
@@ -4,8 +4,8 @@ use superslice::Ext;
4 4
5#[derive(Clone, Debug, PartialEq, Eq)] 5#[derive(Clone, Debug, PartialEq, Eq)]
6pub struct LineIndex { 6pub struct LineIndex {
7 newlines: Vec<TextUnit>, 7 pub(crate) newlines: Vec<TextUnit>,
8 utf16_lines: FxHashMap<u32, Vec<Utf16Char>>, 8 pub(crate) utf16_lines: FxHashMap<u32, Vec<Utf16Char>>,
9} 9}
10 10
11#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 11#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -120,16 +120,6 @@ impl LineIndex {
120 120
121 col 121 col
122 } 122 }
123
124 pub(crate) fn newlines(&self) -> &[TextUnit] {
125 &self.newlines[..]
126 }
127
128 pub(crate) fn utf16_chars(&self, newline_idx: usize) -> Option<&[Utf16Char]> {
129 self.utf16_lines
130 .get(&(newline_idx as u32))
131 .map(|x| x.as_slice())
132 }
133} 123}
134 124
135#[test] 125#[test]
diff --git a/crates/ra_editor/src/line_index_utils.rs b/crates/ra_editor/src/line_index_utils.rs
index 9c8d801e9..382f3ac72 100644
--- a/crates/ra_editor/src/line_index_utils.rs
+++ b/crates/ra_editor/src/line_index_utils.rs
@@ -9,18 +9,17 @@ enum Step {
9 Utf16Char(TextRange), 9 Utf16Char(TextRange),
10} 10}
11 11
12#[derive(Debug)]
12struct LineIndexStepIter<'a> { 13struct LineIndexStepIter<'a> {
13 line_index: &'a LineIndex, 14 line_index: &'a LineIndex,
14 newlines: std::slice::Iter<'a, TextUnit>,
15 next_newline_idx: usize, 15 next_newline_idx: usize,
16 utf16_chars: Option<std::slice::Iter<'a, Utf16Char>>, 16 utf16_chars: Option<(TextUnit, std::slice::Iter<'a, Utf16Char>)>,
17} 17}
18 18
19impl<'a> LineIndexStepIter<'a> { 19impl<'a> LineIndexStepIter<'a> {
20 fn from(line_index: &LineIndex) -> LineIndexStepIter { 20 fn from(line_index: &LineIndex) -> LineIndexStepIter {
21 let mut x = LineIndexStepIter { 21 let mut x = LineIndexStepIter {
22 line_index, 22 line_index,
23 newlines: line_index.newlines().iter(),
24 next_newline_idx: 0, 23 next_newline_idx: 0,
25 utf16_chars: None, 24 utf16_chars: None,
26 }; 25 };
@@ -35,20 +34,22 @@ impl<'a> Iterator for LineIndexStepIter<'a> {
35 fn next(&mut self) -> Option<Step> { 34 fn next(&mut self) -> Option<Step> {
36 self.utf16_chars 35 self.utf16_chars
37 .as_mut() 36 .as_mut()
38 .and_then(|x| { 37 .and_then(|(newline, x)| {
39 None 38 let x = x.next()?;
40 // TODO Enable 39 Some(Step::Utf16Char(TextRange::from_to(
41 // let x = x.next()?; 40 *newline + x.start,
42 // Some(Step::Utf16Char(TextRange::from_to(x.start, x.end))) 41 *newline + x.end,
42 )))
43 }) 43 })
44 .or_else(|| { 44 .or_else(|| {
45 let next_newline = *self.line_index.newlines.get(self.next_newline_idx)?;
45 self.utf16_chars = self 46 self.utf16_chars = self
46 .line_index 47 .line_index
47 .utf16_chars(self.next_newline_idx) 48 .utf16_lines
48 .map(|x| x.iter()); 49 .get(&(self.next_newline_idx as u32))
50 .map(|x| (next_newline, x.iter()));
49 self.next_newline_idx += 1; 51 self.next_newline_idx += 1;
50 let x = self.newlines.next()?; 52 Some(Step::Newline(next_newline))
51 Some(Step::Newline(*x))
52 }) 53 })
53 } 54 }
54} 55}
@@ -71,18 +72,16 @@ impl<'a> Iterator for OffsetNewlineIter<'a> {
71 let next = Step::Newline(next_offset); 72 let next = Step::Newline(next_offset);
72 Some((next, next_offset)) 73 Some((next, next_offset))
73 } else { 74 } else {
74 None 75 let char_len = TextUnit::of_char(c);
75 // TODO enable 76 if char_len.to_usize() > 1 {
76 // let char_len = TextUnit::of_char(c); 77 let start = self.offset + TextUnit::from_usize(i);
77 // if char_len.to_usize() > 1 { 78 let end = start + char_len;
78 // let start = self.offset + TextUnit::from_usize(i); 79 let next = Step::Utf16Char(TextRange::from_to(start, end));
79 // let end = start + char_len; 80 let next_offset = end;
80 // let next = Step::Utf16Char(TextRange::from_to(start, end)); 81 Some((next, next_offset))
81 // let next_offset = end; 82 } else {
82 // Some((next, next_offset)) 83 None
83 // } else { 84 }
84 // None
85 // }
86 } 85 }
87 }) 86 })
88 .next()?; 87 .next()?;
@@ -155,7 +154,7 @@ impl<'a, 'b> Edits<'a, 'b> {
155 fn next_step(&mut self, step: &Step) -> NextNewlines { 154 fn next_step(&mut self, step: &Step) -> NextNewlines {
156 let step_pos = match step { 155 let step_pos = match step {
157 &Step::Newline(n) => n, 156 &Step::Newline(n) => n,
158 &Step::Utf16Char(r) => unimplemented!(), 157 &Step::Utf16Char(r) => r.start(),
159 }; 158 };
160 let res = match &mut self.current { 159 let res = match &mut self.current {
161 Some(edit) => { 160 Some(edit) => {
@@ -215,7 +214,11 @@ impl<'a, 'b> Edits<'a, 'b> {
215 } 214 }
216} 215}
217 216
218pub fn count_newlines(offset: TextUnit, line_index: &LineIndex, edits: &[AtomTextEdit]) -> u32 { 217pub fn translate_offset_with_edit(
218 line_index: &LineIndex,
219 offset: TextUnit,
220 edits: &[AtomTextEdit],
221) -> LineCol {
219 let mut sorted_edits: Vec<&AtomTextEdit> = Vec::with_capacity(edits.len()); 222 let mut sorted_edits: Vec<&AtomTextEdit> = Vec::with_capacity(edits.len());
220 for edit in edits { 223 for edit in edits {
221 let insert_index = 224 let insert_index =
@@ -225,29 +228,55 @@ pub fn count_newlines(offset: TextUnit, line_index: &LineIndex, edits: &[AtomTex
225 228
226 let mut state = Edits::new(&sorted_edits); 229 let mut state = Edits::new(&sorted_edits);
227 230
228 let mut lines: u32 = 0; 231 let mut pos: LineCol = LineCol {
232 line: 0,
233 col_utf16: 0,
234 };
235
236 let mut last_newline: TextUnit = TextUnit::from(0);
237 let mut col_adjust: TextUnit = TextUnit::from(0);
229 238
230 macro_rules! test_step { 239 macro_rules! test_step {
231 ($x:ident) => { 240 ($x:ident) => {
232 match &$x { 241 match &$x {
233 Step::Newline(n) => { 242 Step::Newline(n) => {
234 if offset < *n { 243 if offset < *n {
235 return lines; 244 return_pos!();
245 } else if offset == *n {
246 pos.line += 1;
247 pos.col_utf16 = 0;
248 return pos;
236 } else { 249 } else {
237 lines += 1; 250 pos.line += 1;
251 pos.col_utf16 = 0;
252 last_newline = *n;
253 col_adjust = TextUnit::from(0);
254 }
255 }
256 Step::Utf16Char(x) => {
257 if offset < x.end() {
258 return_pos!();
259 } else {
260 col_adjust += x.len() - TextUnit::from(1);
238 } 261 }
239 } 262 }
240 Step::Utf16Char(x) => unimplemented!(),
241 } 263 }
242 }; 264 };
243 } 265 }
244 266
267 macro_rules! return_pos {
268 () => {
269 pos.col_utf16 = ((offset - last_newline) - col_adjust).into();
270 return pos;
271 };
272 }
273
245 for orig_step in LineIndexStepIter::from(line_index) { 274 for orig_step in LineIndexStepIter::from(line_index) {
246 loop { 275 loop {
247 let translated_newline = state.translate_step(&orig_step); 276 let translated_step = state.translate_step(&orig_step);
248 match state.next_step(&translated_newline) { 277 match state.next_step(&translated_step) {
249 NextNewlines::Use => { 278 NextNewlines::Use => {
250 test_step!(translated_newline); 279 test_step!(translated_step);
251 break; 280 break;
252 } 281 }
253 NextNewlines::ReplaceMany(ns) => { 282 NextNewlines::ReplaceMany(ns) => {
@@ -276,7 +305,7 @@ pub fn count_newlines(offset: TextUnit, line_index: &LineIndex, edits: &[AtomTex
276 } 305 }
277 } 306 }
278 307
279 lines 308 return_pos!();
280} 309}
281 310
282// for bench 311// for bench
@@ -337,8 +366,9 @@ mod test {
337 fn test_translate_offset_with_edit(x in arb_text_with_offset_and_edits()) { 366 fn test_translate_offset_with_edit(x in arb_text_with_offset_and_edits()) {
338 let line_index = LineIndex::new(&x.text); 367 let line_index = LineIndex::new(&x.text);
339 let expected = translate_after_edit(&x.text, x.offset, x.edits.clone()); 368 let expected = translate_after_edit(&x.text, x.offset, x.edits.clone());
340 let actual_lines = count_newlines(x.offset, &line_index, &x.edits); 369 let actual = translate_offset_with_edit(&line_index, x.offset, &x.edits);
341 assert_eq!(actual_lines, expected.line); 370 // assert_eq!(actual, expected);
371 assert_eq!(actual.line, expected.line);
342 } 372 }
343 } 373 }
344} 374}