vim: Fix changing and deleting surrounding quotes on soft wrapped lines
`cs"` and `ds"` did nothing when the line was soft wrapped and the quotes ended up on different display rows. Quote objects only match on a single line, and the surround code checked that by comparing display rows of the cursor and the found pair, so a soft wrapped line looked like several. The pair itself is found in the buffer text and was already correct. Compare buffer rows instead, in both `ds` and `cs`. This also covers `AnyQuotes` and `MiniQuotes`, which go through the same check. Closes #43069
This commit is contained in:
1 parent
f63c81cdcd
commit
3a969493f7
1 file changed
+51
-5
@@ -213,9 +213,12 @@ impl Vim {
|
||||
if let Some(range) = pair_object.range(&display_map, *selection, true, None) {
|
||||
// If the current parenthesis object is single-line,
|
||||
// then we need to filter whether it is the current line or not
|
||||
// (buffer rows, so that a soft wrapped line still counts as one)
|
||||
if !pair_object.is_multiline() {
|
||||
let is_same_row = selection.start.row() == range.start.row()
|
||||
&& selection.end.row() == range.end.row();
|
||||
let is_same_row = selection.start.to_point(&display_map).row
|
||||
== range.start.to_point(&display_map).row
|
||||
&& selection.end.to_point(&display_map).row
|
||||
== range.end.to_point(&display_map).row;
|
||||
if !is_same_row {
|
||||
anchors.push(start..start);
|
||||
continue;
|
||||
@@ -423,8 +426,10 @@ impl Vim {
|
||||
.range(&display_map, *selection, true, None)
|
||||
.filter(|range| {
|
||||
object.is_multiline()
|
||||
|| (selection.start.row() == range.start.row()
|
||||
&& selection.end.row() == range.end.row())
|
||||
|| (selection.start.to_point(&display_map).row
|
||||
== range.start.to_point(&display_map).row
|
||||
&& selection.end.to_point(&display_map).row
|
||||
== range.end.to_point(&display_map).row)
|
||||
});
|
||||
let Some(range) = in_range else {
|
||||
updated_cursor_ranges.push(start..start);
|
||||
@@ -659,8 +664,10 @@ pub fn bracket_pair_for_str_helix(text: &str) -> BracketPair {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use gpui::KeyBinding;
|
||||
use gpui::{KeyBinding, UpdateGlobal};
|
||||
use indoc::indoc;
|
||||
use language::language_settings::SoftWrap;
|
||||
use settings::SettingsStore;
|
||||
|
||||
use crate::{
|
||||
PushAddSurrounds,
|
||||
@@ -1584,6 +1591,45 @@ mod test {
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_surrounds_with_soft_wrap(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
cx.update(|_, cx| {
|
||||
SettingsStore::update_global(cx, |settings, cx| {
|
||||
settings.update_user_settings(cx, |settings| {
|
||||
settings.project.all_languages.defaults.soft_wrap = Some(SoftWrap::Bounded);
|
||||
settings
|
||||
.project
|
||||
.all_languages
|
||||
.defaults
|
||||
.preferred_line_length = Some(20);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
let wrapped_line = "let s = \"a string that is long enough to wrap ˇacross several rows\";";
|
||||
|
||||
cx.set_state(wrapped_line, Mode::Normal);
|
||||
cx.update_editor(|editor, _, cx| {
|
||||
assert!(
|
||||
editor.display_snapshot(cx).max_point().row().0 > 0,
|
||||
"the line should be soft wrapped"
|
||||
);
|
||||
});
|
||||
cx.simulate_keystrokes("c s \" '");
|
||||
cx.assert_state(
|
||||
"let s = ˇ'a string that is long enough to wrap across several rows';",
|
||||
Mode::Normal,
|
||||
);
|
||||
|
||||
cx.set_state(wrapped_line, Mode::Normal);
|
||||
cx.simulate_keystrokes("d s \"");
|
||||
cx.assert_state(
|
||||
"let s = ˇa string that is long enough to wrap across several rows;",
|
||||
Mode::Normal,
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_surround_aliases(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
|
||||
Reference in new issue
Block a user