diff --git a/crates/vim/src/motion.rs b/crates/vim/src/motion.rs index b207307f2d..080f051db5 100644 --- a/crates/vim/src/motion.rs +++ b/crates/vim/src/motion.rs @@ -1701,7 +1701,9 @@ fn previous_word_end( let mut point = point.to_point(map); if point.column < map.buffer_snapshot.line_len(MultiBufferRow(point.row)) { - point.column += 1; + if let Some(ch) = map.buffer_snapshot.chars_at(point).next() { + point.column += ch.len_utf8() as u32; + } } for _ in 0..times { let new_point = movement::find_preceding_boundary_point( @@ -1874,7 +1876,9 @@ fn previous_subword_end( let mut point = point.to_point(map); if point.column < map.buffer_snapshot.line_len(MultiBufferRow(point.row)) { - point.column += 1; + if let Some(ch) = map.buffer_snapshot.chars_at(point).next() { + point.column += ch.len_utf8() as u32; + } } for _ in 0..times { let new_point = movement::find_preceding_boundary_point( @@ -3613,6 +3617,16 @@ mod test { 4;5.6 567 678 789 890 901 "}); + + // With multi byte char + cx.set_shared_state(indoc! {r" + bar ˇó + "}) + .await; + cx.simulate_shared_keystrokes("g e").await; + cx.shared_state().await.assert_eq(indoc! {" + baˇr ó + "}); } #[gpui::test] diff --git a/crates/vim/test_data/test_previous_word_end.json b/crates/vim/test_data/test_previous_word_end.json index 11e7552ce9..f1e3540240 100644 --- a/crates/vim/test_data/test_previous_word_end.json +++ b/crates/vim/test_data/test_previous_word_end.json @@ -27,3 +27,7 @@ {"Key":"g"} {"Key":"shift-e"} {"Get":{"state":"123 234 34ˇ5\n4;5.6 567 678\n789 890 901\n","mode":"Normal"}} +{"Put":{"state":"bar ˇó\n"}} +{"Key":"g"} +{"Key":"e"} +{"Get":{"state":"baˇr ó\n","mode":"Normal"}}