diff --git a/crates/vim/src/normal/search.rs b/crates/vim/src/normal/search.rs index 6ac123ea1e..c579d8ff7e 100644 --- a/crates/vim/src/normal/search.rs +++ b/crates/vim/src/normal/search.rs @@ -2,6 +2,7 @@ use std::{ops::Range, sync::OnceLock, time::Duration}; use gpui::{actions, impl_actions, ViewContext}; use language::Point; +use multi_buffer::MultiBufferRow; use regex::Regex; use search::{buffer_search, BufferSearchBar, SearchOptions}; use serde_derive::Deserialize; @@ -362,9 +363,11 @@ fn replace_command( if let Some(editor) = editor.as_mut() { editor.update(cx, |editor, cx| { let snapshot = &editor.snapshot(cx).buffer_snapshot; + let end_row = MultiBufferRow(range.end.saturating_sub(1) as u32); + let end_point = Point::new(end_row.0, snapshot.line_len(end_row)); let range = snapshot .anchor_before(Point::new(range.start.saturating_sub(1) as u32, 0)) - ..snapshot.anchor_before(Point::new(range.end as u32, 0)); + ..snapshot.anchor_after(end_point); editor.set_search_within_ranges(&[range], cx) }) } @@ -727,6 +730,50 @@ mod test { }); } + // cargo test -p vim --features neovim test_replace_with_range_at_start + #[gpui::test] + async fn test_replace_with_range_at_start(cx: &mut gpui::TestAppContext) { + let mut cx = NeovimBackedTestContext::new(cx).await; + + cx.set_shared_state(indoc! { + "ˇa + a + a + a + a + a + a + " + }) + .await; + cx.simulate_shared_keystrokes(": 2 , 5 s / ^ / b").await; + cx.simulate_shared_keystrokes("enter").await; + cx.shared_state().await.assert_eq(indoc! { + "a + ba + ba + ba + ˇba + a + a + " + }); + cx.executor().advance_clock(Duration::from_millis(250)); + cx.run_until_parked(); + + cx.simulate_shared_keystrokes("/ a enter").await; + cx.shared_state().await.assert_eq(indoc! { + "a + ba + ba + ba + bˇa + a + a + " + }); + } + // cargo test -p vim --features neovim test_replace_with_range #[gpui::test] async fn test_replace_with_range(cx: &mut gpui::TestAppContext) { diff --git a/crates/vim/test_data/test_replace_with_range_at_start.json b/crates/vim/test_data/test_replace_with_range_at_start.json new file mode 100644 index 0000000000..e3810a7ba2 --- /dev/null +++ b/crates/vim/test_data/test_replace_with_range_at_start.json @@ -0,0 +1,16 @@ +{"Put":{"state":"ˇa\na\na\na\na\na\na\n "}} +{"Key":":"} +{"Key":"2"} +{"Key":","} +{"Key":"5"} +{"Key":"s"} +{"Key":"/"} +{"Key":"^"} +{"Key":"/"} +{"Key":"b"} +{"Key":"enter"} +{"Get":{"state":"a\nba\nba\nba\nˇba\na\na\n ","mode":"Normal"}} +{"Key":"/"} +{"Key":"a"} +{"Key":"enter"} +{"Get":{"state":"a\nba\nba\nba\nbˇa\na\na\n ","mode":"Normal"}}