aboutsummaryrefslogtreecommitdiff
path: root/helix-core/src/test.rs
diff options
context:
space:
mode:
authorSkyler Hawthorne2022-10-21 00:22:20 +0000
committerGitHub2022-10-21 00:22:20 +0000
commit6a0b450f55675c76d67bfb026caa2df4b601153b (patch)
treec4048bf2a421549b6d2c068b94fa1088db37752f /helix-core/src/test.rs
parente25af1f7441fd1eccae580ba2e8e0eebc2be74f8 (diff)
Fix multi byte auto pairs (#4024)
* Fix test::print for Unicode The print function was not generating correct translations when the input has Unicode (non-ASCII) in it. This is due to its use of String::len, which gives the length in bytes, not chars. * Fix multi-code point auto pairs The current code for auto pairs is counting offsets by summing the length of the open and closing chars with char::len_utf8. Unfortunately, this gives back bytes, and the offset needs to be in chars. Additionally, it was discovered that there was a preexisting bug where the selection was not computed correctly in the case that the cursor was: 1. a single grapheme in width 2. this grapheme was more than one char 3. the direction of the cursor is backwards 4. a secondary range In this case, the offset was not being added into the anchor. This was fixed. * migrate auto pairs tests to integration * review comments
Diffstat (limited to 'helix-core/src/test.rs')
-rw-r--r--helix-core/src/test.rs127
1 files changed, 124 insertions, 3 deletions
diff --git a/helix-core/src/test.rs b/helix-core/src/test.rs
index 45503107..3e54d2c2 100644
--- a/helix-core/src/test.rs
+++ b/helix-core/src/test.rs
@@ -34,7 +34,7 @@ pub fn print(s: &str) -> (String, Selection) {
let mut left = String::with_capacity(s.len());
'outer: while let Some(c) = iter.next() {
- let start = left.len();
+ let start = left.chars().count();
if c != '#' {
left.push(c);
@@ -63,6 +63,7 @@ pub fn print(s: &str) -> (String, Selection) {
left.push(c);
continue;
}
+
if !head_at_beg {
let prev = left.pop().unwrap();
if prev != '|' {
@@ -71,15 +72,18 @@ pub fn print(s: &str) -> (String, Selection) {
continue;
}
}
+
iter.next(); // skip "#"
if is_primary {
primary_idx = Some(ranges.len());
}
+
let (anchor, head) = match head_at_beg {
- true => (left.len(), start),
- false => (start, left.len()),
+ true => (left.chars().count(), start),
+ false => (start, left.chars().count()),
};
+
ranges.push(Range::new(anchor, head));
continue 'outer;
}
@@ -95,6 +99,7 @@ pub fn print(s: &str) -> (String, Selection) {
Some(i) => i,
None => panic!("missing primary `#[|]#` {:?}", s),
};
+
let selection = Selection::new(ranges, primary);
(left, selection)
}
@@ -141,3 +146,119 @@ pub fn plain(s: &str, selection: Selection) -> String {
}
out
}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn print_single() {
+ assert_eq!(
+ (String::from("hello"), Selection::single(1, 0)),
+ print("#[|h]#ello")
+ );
+ assert_eq!(
+ (String::from("hello"), Selection::single(0, 1)),
+ print("#[h|]#ello")
+ );
+ assert_eq!(
+ (String::from("hello"), Selection::single(4, 0)),
+ print("#[|hell]#o")
+ );
+ assert_eq!(
+ (String::from("hello"), Selection::single(0, 4)),
+ print("#[hell|]#o")
+ );
+ assert_eq!(
+ (String::from("hello"), Selection::single(5, 0)),
+ print("#[|hello]#")
+ );
+ assert_eq!(
+ (String::from("hello"), Selection::single(0, 5)),
+ print("#[hello|]#")
+ );
+ }
+
+ #[test]
+ fn print_multi() {
+ assert_eq!(
+ (
+ String::from("hello"),
+ Selection::new(
+ SmallVec::from_slice(&[Range::new(1, 0), Range::new(5, 4)]),
+ 0
+ )
+ ),
+ print("#[|h]#ell#(|o)#")
+ );
+ assert_eq!(
+ (
+ String::from("hello"),
+ Selection::new(
+ SmallVec::from_slice(&[Range::new(0, 1), Range::new(4, 5)]),
+ 0
+ )
+ ),
+ print("#[h|]#ell#(o|)#")
+ );
+ assert_eq!(
+ (
+ String::from("hello"),
+ Selection::new(
+ SmallVec::from_slice(&[Range::new(2, 0), Range::new(5, 3)]),
+ 0
+ )
+ ),
+ print("#[|he]#l#(|lo)#")
+ );
+ assert_eq!(
+ (
+ String::from("hello\r\nhello\r\nhello\r\n"),
+ Selection::new(
+ SmallVec::from_slice(&[
+ Range::new(7, 5),
+ Range::new(21, 19),
+ Range::new(14, 12)
+ ]),
+ 0
+ )
+ ),
+ print("hello#[|\r\n]#hello#(|\r\n)#hello#(|\r\n)#")
+ );
+ }
+
+ #[test]
+ fn print_multi_byte_code_point() {
+ assert_eq!(
+ (String::from("„“"), Selection::single(1, 0)),
+ print("#[|„]#“")
+ );
+ assert_eq!(
+ (String::from("„“"), Selection::single(2, 1)),
+ print("„#[|“]#")
+ );
+ assert_eq!(
+ (String::from("„“"), Selection::single(0, 1)),
+ print("#[„|]#“")
+ );
+ assert_eq!(
+ (String::from("„“"), Selection::single(1, 2)),
+ print("„#[“|]#")
+ );
+ assert_eq!(
+ (String::from("they said „hello“"), Selection::single(11, 10)),
+ print("they said #[|„]#hello“")
+ );
+ }
+
+ #[test]
+ fn print_multi_code_point_grapheme() {
+ assert_eq!(
+ (
+ String::from("hello 👨‍👩‍👧‍👦 goodbye"),
+ Selection::single(13, 6)
+ ),
+ print("hello #[|👨‍👩‍👧‍👦]# goodbye")
+ );
+ }
+}