Skip to content

Commit

Permalink
Fix range offsets in multi-selection paste (helix-editor#4608)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
the-mikedavis authored and Frederik Vestre committed Feb 6, 2023
1 parent 48d3dff commit 2190be2
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
6 changes: 5 additions & 1 deletion helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand All @@ -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)
});
Expand Down
22 changes: 22 additions & 0 deletions helix-term/tests/test/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}

0 comments on commit 2190be2

Please sign in to comment.