aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurențiu Nicola <[email protected]>2020-05-05 18:29:04 +0100
committerLaurențiu Nicola <[email protected]>2020-05-05 18:30:52 +0100
commit1d794e859028a71d182daf2fa5826aeeeab2876b (patch)
tree981d21ae4344d21df71a549f61973dbe927bb3dc
parent7ec1b63f813e45f26668c2d6d803ec72c3c75738 (diff)
Fix column conversion for supplementary plane characters
-rw-r--r--crates/ra_ide_db/src/line_index.rs17
1 files changed, 15 insertions, 2 deletions
diff --git a/crates/ra_ide_db/src/line_index.rs b/crates/ra_ide_db/src/line_index.rs
index 212cb7b5b..c7c744fce 100644
--- a/crates/ra_ide_db/src/line_index.rs
+++ b/crates/ra_ide_db/src/line_index.rs
@@ -31,9 +31,19 @@ pub(crate) struct Utf16Char {
31} 31}
32 32
33impl Utf16Char { 33impl Utf16Char {
34 /// Returns the length in 8-bit UTF-8 code units.
34 fn len(&self) -> TextSize { 35 fn len(&self) -> TextSize {
35 self.end - self.start 36 self.end - self.start
36 } 37 }
38
39 /// Returns the length in 16-bit UTF-16 code units.
40 fn len_utf16(&self) -> usize {
41 if self.len() == TextSize::from(4) {
42 2
43 } else {
44 1
45 }
46 }
37} 47}
38 48
39impl LineIndex { 49impl LineIndex {
@@ -110,7 +120,7 @@ impl LineIndex {
110 if let Some(utf16_chars) = self.utf16_lines.get(&line) { 120 if let Some(utf16_chars) = self.utf16_lines.get(&line) {
111 for c in utf16_chars { 121 for c in utf16_chars {
112 if c.end <= col { 122 if c.end <= col {
113 res -= usize::from(c.len()) - 1; 123 res -= usize::from(c.len()) - c.len_utf16();
114 } else { 124 } else {
115 // From here on, all utf16 characters come *after* the character we are mapping, 125 // From here on, all utf16 characters come *after* the character we are mapping,
116 // so we don't need to take them into account 126 // so we don't need to take them into account
@@ -125,7 +135,7 @@ impl LineIndex {
125 if let Some(utf16_chars) = self.utf16_lines.get(&line) { 135 if let Some(utf16_chars) = self.utf16_lines.get(&line) {
126 for c in utf16_chars { 136 for c in utf16_chars {
127 if col > u32::from(c.start) { 137 if col > u32::from(c.start) {
128 col += u32::from(c.len()) - 1; 138 col += u32::from(c.len()) - c.len_utf16() as u32;
129 } else { 139 } else {
130 // From here on, all utf16 characters come *after* the character we are mapping, 140 // From here on, all utf16 characters come *after* the character we are mapping,
131 // so we don't need to take them into account 141 // so we don't need to take them into account
@@ -204,6 +214,9 @@ const C: char = 'メ';
204 214
205 // UTF-16 to UTF-8 215 // UTF-16 to UTF-8
206 assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextSize::from(21)); 216 assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextSize::from(21));
217
218 let col_index = LineIndex::new("a𐐏b");
219 assert_eq!(col_index.utf16_to_utf8_col(0, 3), TextSize::from(5));
207 } 220 }
208 221
209 #[test] 222 #[test]