From 066e938ba083c0259ff411b681eca7bad30980df Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 2 Feb 2025 20:46:14 -0500 Subject: [PATCH] Add `copy_between_registers` for interactive register copying --- book/src/generated/static-cmd.md | 1 + helix-term/src/commands.rs | 36 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/book/src/generated/static-cmd.md b/book/src/generated/static-cmd.md index ed31f0b1f..af7515b8e 100644 --- a/book/src/generated/static-cmd.md +++ b/book/src/generated/static-cmd.md @@ -239,6 +239,7 @@ | `wonly` | Close windows except current | normal: `` o ``, `` wo ``, `` ``, `` w ``, select: `` o ``, `` wo ``, `` ``, `` w `` | | `select_register` | Select register | normal: `` " ``, select: `` " `` | | `insert_register` | Insert register | insert: `` `` | +| `copy_between_registers` | Copy between two registers | | | `align_view_middle` | Align view middle | normal: `` Zm ``, `` zm ``, select: `` Zm ``, `` zm `` | | `align_view_top` | Align view top | normal: `` Zt ``, `` zt ``, select: `` Zt ``, `` zt `` | | `align_view_center` | Align view center | normal: `` Zc ``, `` Zz ``, `` zc ``, `` zz ``, select: `` Zc ``, `` Zz ``, `` zc ``, `` zz `` | diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index cd296f867..19a22601e 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -532,6 +532,7 @@ impl MappableCommand { wonly, "Close windows except current", select_register, "Select register", insert_register, "Insert register", + copy_between_registers, "Copy between two registers", align_view_middle, "Align view middle", align_view_top, "Align view top", align_view_center, "Align view center", @@ -5569,6 +5570,41 @@ fn insert_register(cx: &mut Context) { }) } +fn copy_between_registers(cx: &mut Context) { + cx.editor.autoinfo = Some(Info::from_registers(&cx.editor.registers)); + cx.on_next_key(move |cx, event| { + cx.editor.autoinfo = None; + + let Some(source) = event.char() else { + return; + }; + + let Some(values) = cx.editor.registers.read(source, cx.editor) else { + cx.editor.set_error(format!("register {source} is empty")); + return; + }; + let values: Vec<_> = values.map(|value| value.to_string()).collect(); + + cx.editor.autoinfo = Some(Info::from_registers(&cx.editor.registers)); + cx.on_next_key(move |cx, event| { + cx.editor.autoinfo = None; + + let Some(dest) = event.char() else { + return; + }; + + let n_values = values.len(); + match cx.editor.registers.write(dest, values) { + Ok(_) => cx.editor.set_status(format!( + "yanked {n_values} value{} from register {source} to {dest}", + if n_values == 1 { "" } else { "s" } + )), + Err(err) => cx.editor.set_error(err.to_string()), + } + }); + }); +} + fn align_view_top(cx: &mut Context) { let (view, doc) = current!(cx.editor); align_view(doc, view, Align::Top);