Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--helix-term/src/commands.rs6
-rw-r--r--helix-term/tests/test/commands/insert.rs121
2 files changed, 126 insertions, 1 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 3b906487..755a7dc0 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -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,
diff --git a/helix-term/tests/test/commands/insert.rs b/helix-term/tests/test/commands/insert.rs
index f7aa4a02..f23876df 100644
--- a/helix-term/tests/test/commands/insert.rs
+++ b/helix-term/tests/test/commands/insert.rs
@@ -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<()> {