aboutsummaryrefslogtreecommitdiff
path: root/helix-core
diff options
context:
space:
mode:
Diffstat (limited to 'helix-core')
-rw-r--r--helix-core/src/movement.rs5
-rw-r--r--helix-core/src/selection.rs2
-rw-r--r--helix-core/src/transaction.rs20
3 files changed, 24 insertions, 3 deletions
diff --git a/helix-core/src/movement.rs b/helix-core/src/movement.rs
index 387b59b1..d6745fff 100644
--- a/helix-core/src/movement.rs
+++ b/helix-core/src/movement.rs
@@ -45,7 +45,10 @@ pub fn move_vertically(
let new_line = match dir {
Direction::Backward => row.saturating_sub(count),
- Direction::Forward => std::cmp::min(row.saturating_add(count), text.len_lines() - 2),
+ Direction::Forward => std::cmp::min(
+ row.saturating_add(count),
+ text.len_lines().saturating_sub(2),
+ ),
};
// convert to 0-indexed, subtract another 1 because len_chars() counts \n
diff --git a/helix-core/src/selection.rs b/helix-core/src/selection.rs
index 67a20934..7dafc97a 100644
--- a/helix-core/src/selection.rs
+++ b/helix-core/src/selection.rs
@@ -383,7 +383,7 @@ pub fn split_on_matches(
// TODO: retain range direction
let end = text.byte_to_char(start_byte + mat.start());
- result.push(Range::new(start, end - 1));
+ result.push(Range::new(start, end.saturating_sub(1)));
start = text.byte_to_char(start_byte + mat.end());
}
diff --git a/helix-core/src/transaction.rs b/helix-core/src/transaction.rs
index e61063f0..085f40b7 100644
--- a/helix-core/src/transaction.rs
+++ b/helix-core/src/transaction.rs
@@ -90,7 +90,8 @@ impl ChangeSet {
return;
}
- self.len_after += fragment.len();
+ // Avoiding std::str::len() to account for UTF-8 characters.
+ self.len_after += fragment.chars().count();
let new_last = match self.changes.as_mut_slice() {
[.., Insert(prev)] | [.., Insert(prev), Delete(_)] => {
@@ -754,4 +755,21 @@ mod test {
use Operation::*;
assert_eq!(changes.changes, &[Insert("a".into())]);
}
+
+ #[test]
+ fn combine_with_utf8() {
+ const TEST_CASE: &'static str = "Hello, これはヒレクスエディターです!";
+
+ let empty = Rope::from("");
+ let mut a = ChangeSet::new(&empty);
+
+ let mut b = ChangeSet::new(&empty);
+ b.insert(TEST_CASE.into());
+
+ let changes = a.compose(b);
+
+ use Operation::*;
+ assert_eq!(changes.changes, &[Insert(TEST_CASE.into())]);
+ assert_eq!(changes.len_after, TEST_CASE.chars().count());
+ }
}