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 let Some(range) = pair_object.range(&display_map, *selection, true, None) {
|
||||||
// If the current parenthesis object is single-line,
|
// If the current parenthesis object is single-line,
|
||||||
// then we need to filter whether it is the current line or not
|
// 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() {
|
if !pair_object.is_multiline() {
|
||||||
let is_same_row = selection.start.row() == range.start.row()
|
let is_same_row = selection.start.to_point(&display_map).row
|
||||||
&& selection.end.row() == range.end.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 {
|
if !is_same_row {
|
||||||
anchors.push(start..start);
|
anchors.push(start..start);
|
||||||
continue;
|
continue;
|
||||||
@@ -423,8 +426,10 @@ impl Vim {
|
|||||||
.range(&display_map, *selection, true, None)
|
.range(&display_map, *selection, true, None)
|
||||||
.filter(|range| {
|
.filter(|range| {
|
||||||
object.is_multiline()
|
object.is_multiline()
|
||||||
|| (selection.start.row() == range.start.row()
|
|| (selection.start.to_point(&display_map).row
|
||||||
&& selection.end.row() == range.end.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 {
|
let Some(range) = in_range else {
|
||||||
updated_cursor_ranges.push(start..start);
|
updated_cursor_ranges.push(start..start);
|
||||||
@@ -659,8 +664,10 @@ pub fn bracket_pair_for_str_helix(text: &str) -> BracketPair {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use gpui::KeyBinding;
|
use gpui::{KeyBinding, UpdateGlobal};
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
|
use language::language_settings::SoftWrap;
|
||||||
|
use settings::SettingsStore;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
PushAddSurrounds,
|
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]
|
#[gpui::test]
|
||||||
async fn test_surround_aliases(cx: &mut gpui::TestAppContext) {
|
async fn test_surround_aliases(cx: &mut gpui::TestAppContext) {
|
||||||
let mut cx = VimTestContext::new(cx, true).await;
|
let mut cx = VimTestContext::new(cx, true).await;
|
||||||
|
|||||||
Reference in new issue
Block a user