diff --git a/crates/vim/src/object.rs b/crates/vim/src/object.rs index 285f79095a..eb2999cb72 100644 --- a/crates/vim/src/object.rs +++ b/crates/vim/src/object.rs @@ -1339,14 +1339,20 @@ fn surrounding_markers( } } + let mut last_newline_end = None; for (ch, range) in movement::chars_before(map, closing.start) { if !ch.is_whitespace() { break; } - if ch != '\n' { - closing.start = range.start + if ch == '\n' { + last_newline_end = Some(range.end); + break; } } + // Adjust closing.start to exclude whitespace after a newline, if present + if let Some(end) = last_newline_end { + closing.start = end; + } } let result = if around { @@ -2254,6 +2260,20 @@ mod test { } } + #[gpui::test] + async fn test_anybrackets_trailing_space(cx: &mut gpui::TestAppContext) { + let mut cx = NeovimBackedTestContext::new(cx).await; + + cx.set_shared_state("(trailingˇ whitespace )") + .await; + cx.simulate_shared_keystrokes("v i b").await; + cx.shared_state().await.assert_matches(); + cx.simulate_shared_keystrokes("escape y i b").await; + cx.shared_clipboard() + .await + .assert_eq("trailing whitespace "); + } + #[gpui::test] async fn test_tags(cx: &mut gpui::TestAppContext) { let mut cx = VimTestContext::new_html(cx).await; diff --git a/crates/vim/test_data/test_anybrackets_trailing_space.json b/crates/vim/test_data/test_anybrackets_trailing_space.json new file mode 100644 index 0000000000..ed3f47df6c --- /dev/null +++ b/crates/vim/test_data/test_anybrackets_trailing_space.json @@ -0,0 +1,11 @@ +{"Put":{"state":"(trailingˇ whitespace )"}} +{"Key":"v"} +{"Key":"i"} +{"Key":"b"} +{"Get":{"state":"(«trailing whitespace ˇ»)","mode":"Visual"}} +{"Key":"escape"} +{"Key":"y"} +{"Key":"i"} +{"Key":"b"} +{"Get":{"state":"(ˇtrailing whitespace )","mode":"Normal"}} +{"ReadRegister":{"name":"\"","value":"trailing whitespace "}}