Fix open_{below, above}
behaviour with multiple cursors (#12465)
This commit is contained in:
parent
134aebf8cc
commit
60bff8feee
2 changed files with 126 additions and 1 deletions
|
@ -3474,6 +3474,7 @@ fn open(cx: &mut Context, open: Open) {
|
||||||
let text = doc.text().slice(..);
|
let text = doc.text().slice(..);
|
||||||
let contents = doc.text();
|
let contents = doc.text();
|
||||||
let selection = doc.selection(view.id);
|
let selection = doc.selection(view.id);
|
||||||
|
let mut offs = 0;
|
||||||
|
|
||||||
let mut ranges = SmallVec::with_capacity(selection.len());
|
let mut ranges = SmallVec::with_capacity(selection.len());
|
||||||
|
|
||||||
|
@ -3550,7 +3551,7 @@ fn open(cx: &mut Context, open: Open) {
|
||||||
let text = text.repeat(count);
|
let text = text.repeat(count);
|
||||||
|
|
||||||
// calculate new selection ranges
|
// 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
|
let comment_len = continue_comment_token
|
||||||
.map(|token| token.len() + 1) // `+ 1` for the extra space added
|
.map(|token| token.len() + 1) // `+ 1` for the extra space added
|
||||||
.unwrap_or_default();
|
.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,
|
||||||
above_next_line_end_index,
|
above_next_line_end_index,
|
||||||
|
|
|
@ -184,6 +184,127 @@ async fn test_open_above() -> anyhow::Result<()> {
|
||||||
Ok(())
|
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.
|
/// NOTE: To make the `open_above` comment-aware, we're setting the language for each test to rust.
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn test_open_above_with_comments() -> anyhow::Result<()> {
|
async fn test_open_above_with_comments() -> anyhow::Result<()> {
|
||||||
|
|
Loading…
Reference in a new issue