on master help sign in
Improve coords_at_pos & pos_at_coords, test with graphemes.
commitf118e7580f823aec9cb9801d4149f67d009394a4 authorBlaž Hrastnik <blaz@mxxn.io> dateWed 24 Feb 2021, 16:08 (6 years ago) parent87a6d4e
1 file changed+38−5
helix-core/src/state.rs+38−5
helix-core/src/state.rs+38−5
@@ -217,7 +217,7 @@ impl State {
217217pub fn coords_at_pos(text: RopeSlice, pos: usize) -> Position {
218218 let line = text.char_to_line(pos);
219219 let line_start = text.line_to_char(line);
220− let col = text.slice(line_start..pos).len_chars();
220+ let col = RopeGraphemes::new(text.slice(line_start..pos)).count();
221221 Position::new(line, col)
222222}
223223
@@ -225,6 +225,7 @@ pub fn coords_at_pos(text: RopeSlice, pos: usize) -> Position {
225225pub fn pos_at_coords(text: RopeSlice, coords: Position) -> usize {
226226 let Position { row, col } = coords;
227227 let line_start = text.line_to_char(row);
228+ // line_start + col
228229 nth_next_grapheme_boundary(text, line_start, col)
229230}
230231
@@ -320,11 +321,26 @@ mod test {
320321 fn test_coords_at_pos() {
321322 let text = Rope::from("ḧëḷḷö\nẅöṛḷḋ");
322323 let slice = text.slice(..);
324+ // assert_eq!(coords_at_pos(slice, 0), (0, 0).into());
325+ // assert_eq!(coords_at_pos(slice, 5), (0, 5).into()); // position on \n
326+ // assert_eq!(coords_at_pos(slice, 6), (1, 0).into()); // position on w
327+ // assert_eq!(coords_at_pos(slice, 7), (1, 1).into()); // position on o
328+ // assert_eq!(coords_at_pos(slice, 10), (1, 4).into()); // position on d
329+
330+ // test with grapheme clusters
331+ let text = Rope::from("a̐éö̲\r\n");
332+ let slice = text.slice(..);
323333 assert_eq!(coords_at_pos(slice, 0), (0, 0).into());
324− assert_eq!(coords_at_pos(slice, 5), (0, 5).into()); // position on \n
325− assert_eq!(coords_at_pos(slice, 6), (1, 0).into()); // position on w
326− assert_eq!(coords_at_pos(slice, 7), (1, 1).into()); // position on o
327− assert_eq!(coords_at_pos(slice, 10), (1, 4).into()); // position on d
334+ assert_eq!(coords_at_pos(slice, 2), (0, 1).into());
335+ assert_eq!(coords_at_pos(slice, 4), (0, 2).into());
336+ assert_eq!(coords_at_pos(slice, 7), (0, 3).into());
337+
338+ let text = Rope::from("किमपि");
339+ let slice = text.slice(..);
340+ assert_eq!(coords_at_pos(slice, 0), (0, 0).into());
341+ assert_eq!(coords_at_pos(slice, 2), (0, 1).into());
342+ assert_eq!(coords_at_pos(slice, 3), (0, 2).into());
343+ assert_eq!(coords_at_pos(slice, 5), (0, 3).into());
328344 }
329345
330346 #[test]
@@ -336,6 +352,23 @@ mod test {
336352 assert_eq!(pos_at_coords(slice, (1, 0).into()), 6); // position on w
337353 assert_eq!(pos_at_coords(slice, (1, 1).into()), 7); // position on o
338354 assert_eq!(pos_at_coords(slice, (1, 4).into()), 10); // position on d
355+
356+ // test with grapheme clusters
357+ let text = Rope::from("a̐éö̲\r\n");
358+ let slice = text.slice(..);
359+ assert_eq!(pos_at_coords(slice, (0, 0).into()), 0);
360+ assert_eq!(pos_at_coords(slice, (0, 1).into()), 2);
361+ assert_eq!(pos_at_coords(slice, (0, 2).into()), 4);
362+ assert_eq!(pos_at_coords(slice, (0, 3).into()), 7); // \r\n is one char here
363+ assert_eq!(pos_at_coords(slice, (0, 4).into()), 9);
364+ let text = Rope::from("किमपि");
365+ // 2 - 1 - 2 codepoints
366+ // TODO: delete handling as per https://news.ycombinator.com/item?id=20058454
367+ let slice = text.slice(..);
368+ assert_eq!(pos_at_coords(slice, (0, 0).into()), 0);
369+ assert_eq!(pos_at_coords(slice, (0, 1).into()), 2);
370+ assert_eq!(pos_at_coords(slice, (0, 2).into()), 3);
371+ assert_eq!(pos_at_coords(slice, (0, 3).into()), 5); // eol
339372 }
340373
341374 #[test]