Skip to content

Commit

Permalink
fix(core): match inside closest pair inconsitency
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
woojiq committed Apr 27, 2024
1 parent 109f53f commit 0890141
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 4 deletions.
4 changes: 1 addition & 3 deletions helix-core/src/surround.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
Expand Down
14 changes: 13 additions & 1 deletion helix-core/src/textobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
30 changes: 30 additions & 0 deletions helix-term/tests/test/movement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down

0 comments on commit 0890141

Please sign in to comment.