fix(core): match inside closest pair inconsitency

Make tree-sitter version of matching inside/around to replicate current behavior of plaintext files.
That is:
* match around - always tries to extend a selection to the next pair,
even when the selection is already around a pair.
* match inside - do not extend a selection when it already completely
matches the pairs.
This commit is contained in:
woojiq 2024-04-27 09:30:49 +03:00
parent c6dbb9c270
commit cb5688cb3e
3 changed files with 44 additions and 4 deletions

View File

@ -57,9 +57,7 @@ fn find_nth_closest_pairs_ts(
mut skip: usize,
) -> Result<(usize, usize)> {
let mut opening = range.from();
// We want to expand the selection if we are already on the found pair,
// otherwise we would need to subtract "-1" from "range.to()".
let mut closing = range.to();
let mut closing = range.to() - 1;
while skip > 0 {
closing = find_matching_bracket_fuzzy(syntax, text, closing).ok_or(Error::PairNotFound)?;

View File

@ -229,7 +229,19 @@ fn textobject_pair_surround_impl(
) -> Range {
let pair_pos = match ch {
Some(ch) => surround::find_nth_pairs_pos(slice, ch, range, count),
None => surround::find_nth_closest_pairs_pos(syntax, slice, range, count),
None => {
surround::find_nth_closest_pairs_pos(syntax, slice, range, count).and_then(|closest| {
// Since `find_nth_closest_pairs_pos` takes into accout the closest
// pair even if the range included it entirely, we need to handle this
// edge case separetely. In such cases, we want to actually find the
// next pair.
if Range::new(closest.0, closest.1).len() == range.len() - 1 && count == 1 {
surround::find_nth_closest_pairs_pos(syntax, slice, range, count + 1)
} else {
Ok(closest)
}
})
}
};
pair_pos
.map(|(anchor, head)| match textobject {

View File

@ -409,6 +409,36 @@ async fn match_around_closest_ts() -> anyhow::Result<()> {
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn match_inside_closest_ts() -> anyhow::Result<()> {
test_with_config(
AppBuilder::new().with_file("foo.rs", None),
(
r#"fn main() {func(#["|]#string");}"#,
"mim",
r##"fn main() {func("#[string|]#");}"##,
),
)
.await?;
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn match_mix_closest_ts() -> anyhow::Result<()> {
test_with_config(
AppBuilder::new().with_file("foo.rs", None),
(
r#"fn main() {func("st#[|r]#ing");}"#,
"mimmammimmam",
r#"fn main() {func#[|("string")]#;}"#,
),
)
.await?;
Ok(())
}
/// Ensure the very initial cursor in an opened file is the width of
/// the first grapheme
#[tokio::test(flavor = "multi_thread")]