diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 664db53e1a..8104b0ee9b 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -851,7 +851,7 @@ fn test_move_cursor_multibyte(cx: &mut TestAppContext) { let view = cx .add_window(|cx| { - let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcde\nαβγδε\n", cx); + let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcde\nαβγδε", cx); build_editor(buffer.clone(), cx) }) .root(cx); @@ -869,7 +869,7 @@ fn test_move_cursor_multibyte(cx: &mut TestAppContext) { true, cx, ); - assert_eq!(view.display_text(cx), "ⓐⓑ⋯ⓔ\nab⋯e\nαβ⋯ε\n"); + assert_eq!(view.display_text(cx), "ⓐⓑ⋯ⓔ\nab⋯e\nαβ⋯ε"); view.move_right(&MoveRight, cx); assert_eq!( @@ -934,6 +934,17 @@ fn test_move_cursor_multibyte(cx: &mut TestAppContext) { view.selections.display_ranges(cx), &[empty_range(1, "ab⋯e".len())] ); + view.move_down(&MoveDown, cx); + assert_eq!( + view.selections.display_ranges(cx), + &[empty_range(2, "αβ⋯ε".len())] + ); + view.move_up(&MoveUp, cx); + assert_eq!( + view.selections.display_ranges(cx), + &[empty_range(1, "ab⋯e".len())] + ); + view.move_up(&MoveUp, cx); assert_eq!( view.selections.display_ranges(cx), diff --git a/crates/editor/src/movement.rs b/crates/editor/src/movement.rs index 580faf1050..1bb4154b1f 100644 --- a/crates/editor/src/movement.rs +++ b/crates/editor/src/movement.rs @@ -147,7 +147,9 @@ pub fn down_by_rows( goal_x = map.x_for_point(point, text_layout_details) } + dbg!(point); let mut clipped_point = map.clip_point(point, Bias::Right); + dbg!(clipped_point); if clipped_point.row() > point.row() { clipped_point = map.clip_point(point, Bias::Left); } diff --git a/crates/gpui/src/text_layout.rs b/crates/gpui/src/text_layout.rs index 7fb87b10df..0d0b8bebb5 100644 --- a/crates/gpui/src/text_layout.rs +++ b/crates/gpui/src/text_layout.rs @@ -302,7 +302,11 @@ impl Line { prev_x = glyph.position.x(); } } - prev_index + if self.width() - x < x - prev_x { + prev_index + 1 + } else { + prev_index + } } pub fn paint( diff --git a/crates/vim/src/normal/increment.rs b/crates/vim/src/normal/increment.rs index 9d62f8ab7b..ee70ab1f5d 100644 --- a/crates/vim/src/normal/increment.rs +++ b/crates/vim/src/normal/increment.rs @@ -255,8 +255,18 @@ mod test { 4 5"}) .await; - cx.simulate_shared_keystrokes(["shift-g", "ctrl-v", "g", "g", "g", "ctrl-x"]) + + cx.simulate_shared_keystrokes(["shift-g", "ctrl-v", "g", "g"]) .await; + cx.assert_shared_state(indoc! {" + «1ˇ» + «2ˇ» + «3ˇ» 2 + «4ˇ» + «5ˇ»"}) + .await; + + cx.simulate_shared_keystrokes(["g", "ctrl-x"]).await; cx.assert_shared_state(indoc! {" ˇ0 0 diff --git a/crates/vim/src/visual.rs b/crates/vim/src/visual.rs index 3157374b24..05118e22f8 100644 --- a/crates/vim/src/visual.rs +++ b/crates/vim/src/visual.rs @@ -169,10 +169,10 @@ pub fn visual_block_motion( let is_reversed = tail_x > head_x; if was_reversed && !is_reversed { - tail = movement::left(map, tail); + tail = movement::saturating_left(map, tail); tail_x = map.x_for_point(tail, &text_layout_details); } else if !was_reversed && is_reversed { - tail = movement::right(map, tail); + tail = movement::saturating_right(map, tail); tail_x = map.x_for_point(tail, &text_layout_details); } if !is_reversed && !preserve_goal { @@ -180,8 +180,12 @@ pub fn visual_block_motion( head_x = map.x_for_point(head, &text_layout_details); } + dbg!(head, head_x, tail, tail_x); + let positions = if is_reversed { head_x..tail_x + } else if head_x == tail_x { + map.x_for_point(movement::saturating_left(map, tail), &text_layout_details)..head_x } else { tail_x..head_x }; diff --git a/crates/vim/test_data/test_increment_steps.json b/crates/vim/test_data/test_increment_steps.json index fffaf1fd29..2e8711d1cc 100644 --- a/crates/vim/test_data/test_increment_steps.json +++ b/crates/vim/test_data/test_increment_steps.json @@ -9,6 +9,7 @@ {"Key":"ctrl-v"} {"Key":"g"} {"Key":"g"} +{"Get":{"state":"«1ˇ»\n«2ˇ»\n«3ˇ» 2\n«4ˇ»\n«5ˇ»","mode":"VisualBlock"}} {"Key":"g"} {"Key":"ctrl-x"} {"Get":{"state":"ˇ0\n0\n0 2\n0\n0","mode":"Normal"}}