From 6da2174e14576ff07a0a2a28074fac5276b23d79 Mon Sep 17 00:00:00 2001 From: Omnikar Date: Tue, 14 Dec 2021 03:49:29 -0500 Subject: [PATCH] Allow paste commands to take a count (#1261) * Allow paste commands to take a count * Call `.repeat` within iterator methods * Implement counts for paste-replace --- helix-term/src/commands.rs | 68 +++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 8552f638..cd566720 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2423,7 +2423,7 @@ pub mod cmd { _args: &[Cow], _event: PromptEvent, ) -> anyhow::Result<()> { - paste_clipboard_impl(cx.editor, Paste::After, ClipboardType::Clipboard) + paste_clipboard_impl(cx.editor, Paste::After, ClipboardType::Clipboard, 1) } fn paste_clipboard_before( @@ -2431,7 +2431,7 @@ pub mod cmd { _args: &[Cow], _event: PromptEvent, ) -> anyhow::Result<()> { - paste_clipboard_impl(cx.editor, Paste::After, ClipboardType::Clipboard) + paste_clipboard_impl(cx.editor, Paste::After, ClipboardType::Clipboard, 1) } fn paste_primary_clipboard_after( @@ -2439,7 +2439,7 @@ pub mod cmd { _args: &[Cow], _event: PromptEvent, ) -> anyhow::Result<()> { - paste_clipboard_impl(cx.editor, Paste::After, ClipboardType::Selection) + paste_clipboard_impl(cx.editor, Paste::After, ClipboardType::Selection, 1) } fn paste_primary_clipboard_before( @@ -2447,7 +2447,7 @@ pub mod cmd { _args: &[Cow], _event: PromptEvent, ) -> anyhow::Result<()> { - paste_clipboard_impl(cx.editor, Paste::After, ClipboardType::Selection) + paste_clipboard_impl(cx.editor, Paste::After, ClipboardType::Selection, 1) } fn replace_selections_with_clipboard_impl( @@ -4586,11 +4586,12 @@ fn paste_impl( doc: &mut Document, view: &View, action: Paste, + count: usize, ) -> Option { let repeat = std::iter::repeat( values .last() - .map(|value| Tendril::from_slice(value)) + .map(|value| Tendril::from(value.repeat(count))) .unwrap(), ); @@ -4605,7 +4606,7 @@ fn paste_impl( let mut values = values .iter() .map(|value| REGEX.replace_all(value, doc.line_ending.as_str())) - .map(|value| Tendril::from(value.as_ref())) + .map(|value| Tendril::from(value.as_ref().repeat(count))) .chain(repeat); let text = doc.text(); @@ -4625,7 +4626,7 @@ fn paste_impl( // paste append (Paste::After, false) => range.to(), }; - (pos, pos, Some(values.next().unwrap())) + (pos, pos, values.next()) }); Some(transaction) @@ -4635,13 +4636,14 @@ fn paste_clipboard_impl( editor: &mut Editor, action: Paste, clipboard_type: ClipboardType, + count: usize, ) -> anyhow::Result<()> { let (view, doc) = current!(editor); match editor .clipboard_provider .get_contents(clipboard_type) - .map(|contents| paste_impl(&[contents], doc, view, action)) + .map(|contents| paste_impl(&[contents], doc, view, action, count)) { Ok(Some(transaction)) => { doc.apply(&transaction, view.id); @@ -4654,22 +4656,43 @@ fn paste_clipboard_impl( } fn paste_clipboard_after(cx: &mut Context) { - let _ = paste_clipboard_impl(cx.editor, Paste::After, ClipboardType::Clipboard); + let _ = paste_clipboard_impl( + cx.editor, + Paste::After, + ClipboardType::Clipboard, + cx.count(), + ); } fn paste_clipboard_before(cx: &mut Context) { - let _ = paste_clipboard_impl(cx.editor, Paste::Before, ClipboardType::Clipboard); + let _ = paste_clipboard_impl( + cx.editor, + Paste::Before, + ClipboardType::Clipboard, + cx.count(), + ); } fn paste_primary_clipboard_after(cx: &mut Context) { - let _ = paste_clipboard_impl(cx.editor, Paste::After, ClipboardType::Selection); + let _ = paste_clipboard_impl( + cx.editor, + Paste::After, + ClipboardType::Selection, + cx.count(), + ); } fn paste_primary_clipboard_before(cx: &mut Context) { - let _ = paste_clipboard_impl(cx.editor, Paste::Before, ClipboardType::Selection); + let _ = paste_clipboard_impl( + cx.editor, + Paste::Before, + ClipboardType::Selection, + cx.count(), + ); } fn replace_with_yanked(cx: &mut Context) { + let count = cx.count(); let reg_name = cx.register.unwrap_or('"'); let (view, doc) = current!(cx.editor); let registers = &mut cx.editor.registers; @@ -4679,12 +4702,12 @@ fn replace_with_yanked(cx: &mut Context) { let repeat = std::iter::repeat( values .last() - .map(|value| Tendril::from_slice(value)) + .map(|value| Tendril::from_slice(&value.repeat(count))) .unwrap(), ); let mut values = values .iter() - .map(|value| Tendril::from_slice(value)) + .map(|value| Tendril::from_slice(&value.repeat(count))) .chain(repeat); let selection = doc.selection(view.id); let transaction = Transaction::change_by_selection(doc.text(), selection, |range| { @@ -4704,6 +4727,7 @@ fn replace_with_yanked(cx: &mut Context) { fn replace_selections_with_clipboard_impl( editor: &mut Editor, clipboard_type: ClipboardType, + count: usize, ) -> anyhow::Result<()> { let (view, doc) = current!(editor); @@ -4711,7 +4735,11 @@ fn replace_selections_with_clipboard_impl( Ok(contents) => { let selection = doc.selection(view.id); let transaction = Transaction::change_by_selection(doc.text(), selection, |range| { - (range.from(), range.to(), Some(contents.as_str().into())) + ( + range.from(), + range.to(), + Some(contents.repeat(count).as_str().into()), + ) }); doc.apply(&transaction, view.id); @@ -4723,21 +4751,22 @@ fn replace_selections_with_clipboard_impl( } fn replace_selections_with_clipboard(cx: &mut Context) { - let _ = replace_selections_with_clipboard_impl(cx.editor, ClipboardType::Clipboard); + let _ = replace_selections_with_clipboard_impl(cx.editor, ClipboardType::Clipboard, cx.count()); } fn replace_selections_with_primary_clipboard(cx: &mut Context) { - let _ = replace_selections_with_clipboard_impl(cx.editor, ClipboardType::Selection); + let _ = replace_selections_with_clipboard_impl(cx.editor, ClipboardType::Selection, cx.count()); } fn paste_after(cx: &mut Context) { + let count = cx.count(); let reg_name = cx.register.unwrap_or('"'); let (view, doc) = current!(cx.editor); let registers = &mut cx.editor.registers; if let Some(transaction) = registers .read(reg_name) - .and_then(|values| paste_impl(values, doc, view, Paste::After)) + .and_then(|values| paste_impl(values, doc, view, Paste::After, count)) { doc.apply(&transaction, view.id); doc.append_changes_to_history(view.id); @@ -4745,13 +4774,14 @@ fn paste_after(cx: &mut Context) { } fn paste_before(cx: &mut Context) { + let count = cx.count(); let reg_name = cx.register.unwrap_or('"'); let (view, doc) = current!(cx.editor); let registers = &mut cx.editor.registers; if let Some(transaction) = registers .read(reg_name) - .and_then(|values| paste_impl(values, doc, view, Paste::Before)) + .and_then(|values| paste_impl(values, doc, view, Paste::Before, count)) { doc.apply(&transaction, view.id); doc.append_changes_to_history(view.id);