Nik Revenco 2025-06-07 12:29:44 +01:00 committed by GitHub
commit 856850cca6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 14 deletions

View File

@ -3,7 +3,7 @@ use std::fmt::Display;
use crate::{ use crate::{
graphemes::next_grapheme_boundary, graphemes::next_grapheme_boundary,
match_brackets::{ match_brackets::{
find_matching_bracket, find_matching_bracket_fuzzy, get_pair, is_close_bracket, self, find_matching_bracket, find_matching_bracket_fuzzy, get_pair, is_close_bracket,
is_open_bracket, is_open_bracket,
}, },
movement::Direction, movement::Direction,
@ -162,6 +162,7 @@ pub fn find_nth_pairs_pos(
ch: char, ch: char,
range: Range, range: Range,
n: usize, n: usize,
syntax: Option<&Syntax>,
) -> Result<(usize, usize)> { ) -> Result<(usize, usize)> {
if text.len_chars() < 2 { if text.len_chars() < 2 {
return Err(Error::PairNotFound); return Err(Error::PairNotFound);
@ -175,15 +176,30 @@ pub fn find_nth_pairs_pos(
let (open, close) = if open == close { let (open, close) = if open == close {
if Some(open) == text.get_char(pos) { if Some(open) == text.get_char(pos) {
// Cursor is directly on match char. We return no match // Cursor is directly on match character for which the opening and closing pairs are the same. For instance: ", ', `
// because there's no way to know which side of the char //
// we should be searching on. // This is potentially ambiguous, because there's no way to know which side of the char we should be searching on.
return Err(Error::CursorOnAmbiguousPair); syntax
.map_or_else(
|| match_brackets::find_matching_bracket_plaintext(text.slice(..), pos),
|syntax| {
match_brackets::find_matching_bracket_fuzzy(syntax, text.slice(..), pos)
},
)
.map(|matching_pair_pos| {
if matching_pair_pos > pos {
(Some(pos), Some(matching_pair_pos))
} else {
(Some(matching_pair_pos), Some(pos))
} }
})
.ok_or(Error::CursorOnAmbiguousPair)?
} else {
( (
search::find_nth_prev(text, open, pos, n), search::find_nth_prev(text, open, pos, n),
search::find_nth_next(text, close, pos, n), search::find_nth_next(text, close, pos, n),
) )
}
} else { } else {
( (
find_nth_open_pair(text, open, close, pos, n), find_nth_open_pair(text, open, close, pos, n),
@ -298,7 +314,7 @@ pub fn get_surround_pos(
for &range in selection { for &range in selection {
let (open_pos, close_pos) = { let (open_pos, close_pos) = {
let range_raw = match ch { let range_raw = match ch {
Some(ch) => find_nth_pairs_pos(text, ch, range, skip)?, Some(ch) => find_nth_pairs_pos(text, ch, range, skip, syntax)?,
None => find_nth_closest_pairs_pos(syntax, text, range, skip)?, None => find_nth_closest_pairs_pos(syntax, text, range, skip)?,
}; };
let range = Range::new(range_raw.0, range_raw.1); let range = Range::new(range_raw.0, range_raw.1);
@ -392,7 +408,7 @@ mod test {
assert_eq!(2, expectations.len()); assert_eq!(2, expectations.len());
assert_eq!( assert_eq!(
find_nth_pairs_pos(doc.slice(..), '\'', selection.primary(), 1) find_nth_pairs_pos(doc.slice(..), '\'', selection.primary(), 1, None)
.expect("find should succeed"), .expect("find should succeed"),
(expectations[0], expectations[1]) (expectations[0], expectations[1])
) )
@ -409,7 +425,7 @@ mod test {
assert_eq!(2, expectations.len()); assert_eq!(2, expectations.len());
assert_eq!( assert_eq!(
find_nth_pairs_pos(doc.slice(..), '\'', selection.primary(), 2) find_nth_pairs_pos(doc.slice(..), '\'', selection.primary(), 2, None)
.expect("find should succeed"), .expect("find should succeed"),
(expectations[0], expectations[1]) (expectations[0], expectations[1])
) )
@ -425,7 +441,7 @@ mod test {
); );
assert_eq!( assert_eq!(
find_nth_pairs_pos(doc.slice(..), '\'', selection.primary(), 1), find_nth_pairs_pos(doc.slice(..), '\'', selection.primary(), 1, None),
Err(Error::CursorOnAmbiguousPair) Err(Error::CursorOnAmbiguousPair)
) )
} }

View File

@ -227,7 +227,7 @@ fn textobject_pair_surround_impl(
count: usize, count: usize,
) -> Range { ) -> Range {
let pair_pos = match ch { let pair_pos = match ch {
Some(ch) => surround::find_nth_pairs_pos(slice, ch, range, count), Some(ch) => surround::find_nth_pairs_pos(slice, ch, range, count, syntax),
None => surround::find_nth_closest_pairs_pos(syntax, slice, range, count), None => surround::find_nth_closest_pairs_pos(syntax, slice, range, count),
}; };
pair_pos pair_pos