summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Davis2022-11-06 14:56:45 +0000
committerGitHub2022-11-06 14:56:45 +0000
commit48a3965ab43718ce2a49724cbcc294b04c328b81 (patch)
treef20b4c26a8edc0d096bdd570df3c9cd1f3c0f172
parent4ec2a21c6e21ab4e515f1bd7ee1049094af2a6b2 (diff)
Fix range offsets in multi-selection paste (#4608)
* Fix range offsets in multi-selection paste d6323b7cbc21a9d3ba29738c76581dad93f9f415 introduced a regression with multi-selection paste where pasting would not adjust the ranges correctly. To fix it, we need to track the total number of characters inserted in each changed selection and use that offset to slide each new range forwards. * Inherit selection directions on paste * Add an integration-test for multi-selection pasting
-rw-r--r--helix-term/src/commands.rs6
-rw-r--r--helix-term/tests/test/commands.rs22
2 files changed, 27 insertions, 1 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index ef963477..ae9e35f1 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -3476,6 +3476,7 @@ fn paste_impl(values: &[String], doc: &mut Document, view: &mut View, action: Pa
let text = doc.text();
let selection = doc.selection(view.id);
+ let mut offset = 0;
let mut ranges = SmallVec::with_capacity(selection.len());
let transaction = Transaction::change_by_selection(text, selection, |range| {
@@ -3501,8 +3502,11 @@ fn paste_impl(values: &[String], doc: &mut Document, view: &mut View, action: Pa
.as_ref()
.map(|content| content.chars().count())
.unwrap_or_default();
+ let anchor = offset + pos;
- ranges.push(Range::new(pos, pos + value_len));
+ let new_range = Range::new(anchor, anchor + value_len).with_direction(range.direction());
+ ranges.push(new_range);
+ offset += value_len;
(pos, pos, value)
});
diff --git a/helix-term/tests/test/commands.rs b/helix-term/tests/test/commands.rs
index aadf104b..e78e6c9f 100644
--- a/helix-term/tests/test/commands.rs
+++ b/helix-term/tests/test/commands.rs
@@ -193,3 +193,25 @@ async fn test_goto_file_impl() -> anyhow::Result<()> {
Ok(())
}
+
+#[tokio::test(flavor = "multi_thread")]
+async fn test_multi_selection_paste() -> anyhow::Result<()> {
+ test((
+ platform_line(indoc! {"\
+ #[|lorem]#
+ #(|ipsum)#
+ #(|dolor)#
+ "})
+ .as_str(),
+ "yp",
+ platform_line(indoc! {"\
+ lorem#[|lorem]#
+ ipsum#(|ipsum)#
+ dolor#(|dolor)#
+ "})
+ .as_str(),
+ ))
+ .await?;
+
+ Ok(())
+}