Fix open_{below, above} behaviour with multiple cursors (#12465)

This commit is contained in:
TornaxO7 2025-01-13 15:14:30 +01:00 committed by GitHub
parent 134aebf8cc
commit 60bff8feee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 126 additions and 1 deletions

View file

@ -3474,6 +3474,7 @@ fn open(cx: &mut Context, open: Open) {
let text = doc.text().slice(..);
let contents = doc.text();
let selection = doc.selection(view.id);
let mut offs = 0;
let mut ranges = SmallVec::with_capacity(selection.len());
@ -3550,7 +3551,7 @@ fn open(cx: &mut Context, open: Open) {
let text = text.repeat(count);
// calculate new selection ranges
let pos = above_next_line_end_index + above_next_line_end_width;
let pos = offs + above_next_line_end_index + above_next_line_end_width;
let comment_len = continue_comment_token
.map(|token| token.len() + 1) // `+ 1` for the extra space added
.unwrap_or_default();
@ -3563,6 +3564,9 @@ fn open(cx: &mut Context, open: Open) {
));
}
// update the offset for the next range
offs += text.chars().count();
(
above_next_line_end_index,
above_next_line_end_index,

View file

@ -184,6 +184,127 @@ async fn test_open_above() -> anyhow::Result<()> {
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn test_open_above_with_multiple_cursors() -> anyhow::Result<()> {
// the primary cursor is also in the top line
test((
indoc! {"#[H|]#elix
#(i|)#s
#(c|)#ool"},
"O",
indoc! {
"#[\n|]#
Helix
#(\n|)#
is
#(\n|)#
cool
"
},
))
.await?;
// now with some additional indentation
test((
indoc! {"····#[H|]#elix
····#(i|)#s
····#(c|)#ool"}
.replace("·", " "),
":indent-style 4<ret>O",
indoc! {
"····#[\n|]#
····Helix
····#(\n|)#
····is
····#(\n|)#
····cool
"
}
.replace("·", " "),
))
.await?;
// the first line is within a comment, the second not.
// However, if we open above, the first newly added line should start within a comment
// while the other should be a normal line
test((
indoc! {"fn main() {
// #[VIP|]# comment
l#(e|)#t yes = false;
}"},
":lang rust<ret>O",
indoc! {"fn main() {
// #[\n|]#
// VIP comment
#(\n|)#
let yes = false;
}"},
))
.await?;
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn test_open_below_with_multiple_cursors() -> anyhow::Result<()> {
// the primary cursor is also in the top line
test((
indoc! {"#[H|]#elix
#(i|)#s
#(c|)#ool"},
"o",
indoc! {"Helix
#[\n|]#
is
#(\n|)#
cool
#(\n|)#
"
},
))
.await?;
// now with some additional indentation
test((
indoc! {"····#[H|]#elix
····#(i|)#s
····#(c|)#ool"}
.replace("·", " "),
":indent-style 4<ret>o",
indoc! {
"····Helix
····#[\n|]#
····is
····#(\n|)#
····cool
····#(\n|)#
"
}
.replace("·", " "),
))
.await?;
// the first line is within a comment, the second not.
// However, if we open below, the first newly added line should start within a comment
// while the other should be a normal line
test((
indoc! {"fn main() {
// #[VIP|]# comment
l#(e|)#t yes = false;
}"},
":lang rust<ret>o",
indoc! {"fn main() {
// VIP comment
// #[\n|]#
let yes = false;
#(\n|)#
}"},
))
.await?;
Ok(())
}
/// NOTE: To make the `open_above` comment-aware, we're setting the language for each test to rust.
#[tokio::test(flavor = "multi_thread")]
async fn test_open_above_with_comments() -> anyhow::Result<()> {