on master help sign in
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

commit48a3965ab43718ce2a49724cbcc294b04c328b81 authorMichael Davis <mcarsondavis@gmail.com> dateSun 6 Nov 2022, 08:56 (4 years ago) parent4ec2a21
2 files changed+27−1
helix-term/src/commands.rs+5−1 helix-term/tests/test/commands.rs+22
helix-term/src/commands.rs+5−1
@@ -3476,6 +3476,7 @@ fn paste_impl(values: &[String], doc: &mut Document, view: &mut View, action: Pa
34763476 let text = doc.text();
34773477 let selection = doc.selection(view.id);
34783478
3479+ let mut offset = 0;
34793480 let mut ranges = SmallVec::with_capacity(selection.len());
34803481
34813482 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
35013502 .as_ref()
35023503 .map(|content| content.chars().count())
35033504 .unwrap_or_default();
3505+ let anchor = offset + pos;
35043506
3505− ranges.push(Range::new(pos, pos + value_len));
3507+ let new_range = Range::new(anchor, anchor + value_len).with_direction(range.direction());
3508+ ranges.push(new_range);
3509+ offset += value_len;
35063510
35073511 (pos, pos, value)
35083512 });
helix-term/tests/test/commands.rs+22
@@ -193,3 +193,25 @@ async fn test_goto_file_impl() -> anyhow::Result<()> {
193193
194194 Ok(())
195195}
196+
197+#[tokio::test(flavor = "multi_thread")]
198+async fn test_multi_selection_paste() -> anyhow::Result<()> {
199+ test((
200+ platform_line(indoc! {"\
201+ #[|lorem]#
202+ #(|ipsum)#
203+ #(|dolor)#
204+ "})
205+ .as_str(),
206+ "yp",
207+ platform_line(indoc! {"\
208+ lorem#[|lorem]#
209+ ipsum#(|ipsum)#
210+ dolor#(|dolor)#
211+ "})
212+ .as_str(),
213+ ))
214+ .await?;
215+
216+ Ok(())
217+}