Skip to content

Commit 48a3965

Browse files
Fix range offsets in multi-selection paste (helix-editor#4608)
* Fix range offsets in multi-selection paste d6323b7 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
1 parent 4ec2a21 commit 48a3965

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

helix-term/src/commands.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
}

0 commit comments

Comments
 (0)