From d6323b7cbc21a9d3ba29738c76581dad93f9f415 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Fri, 4 Nov 2022 11:02:19 -0500 Subject: [PATCH] Select text inserted by shell or paste (#4458) This follows changes in Kakoune to the same effects: * p/p: https://github.com/mawww/kakoune/commit/266d1c37d0d970a7eff747f5e6a5773a3cea39d8 * !/: https://github.com/mawww/kakoune/commit/85b78dda2e29d70b620836b04224b104426bdbae Selecting the new data inserted by shell or pasting is often more useful than retaining a selection of the pre-paste/insert content. --- helix-term/src/commands.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index aae9979d00ac..a6ee626305a1 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3471,6 +3471,8 @@ 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 ranges = SmallVec::with_capacity(selection.len()); + let transaction = Transaction::change_by_selection(text, selection, |range| { let pos = match (action, linewise) { // paste linewise before @@ -3487,8 +3489,21 @@ fn paste_impl(values: &[String], doc: &mut Document, view: &mut View, action: Pa // paste at cursor (Paste::Cursor, _) => range.cursor(text.slice(..)), }; - (pos, pos, values.next()) + + let value = values.next(); + + let value_len = value + .as_ref() + .map(|content| content.chars().count()) + .unwrap_or_default(); + + ranges.push(Range::new(pos, pos + value_len)); + + (pos, pos, value) }); + + let transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index())); + apply_transaction(&transaction, doc, view); } @@ -4742,6 +4757,7 @@ fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) { let selection = doc.selection(view.id); let mut changes = Vec::with_capacity(selection.len()); + let mut ranges = SmallVec::with_capacity(selection.len()); let text = doc.text().slice(..); for range in selection.ranges() { @@ -4765,11 +4781,13 @@ fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) { ShellBehavior::Append => (range.to(), range.to()), _ => (range.from(), range.from()), }; + ranges.push(Range::new(to, to + output.chars().count())); changes.push((from, to, Some(output))); } if behavior != &ShellBehavior::Ignore { - let transaction = Transaction::change(doc.text(), changes.into_iter()); + let transaction = Transaction::change(doc.text(), changes.into_iter()) + .with_selection(Selection::new(ranges, selection.primary_index())); apply_transaction(&transaction, doc, view); doc.append_changes_to_history(view.id); }