4

How can I include the contents of a register when recording a macro?

If I use Ctrl+R x I get a "pointer" to register x, i.e., my macro will contain ^Rx instead of the register contents.

Motivation:

Often I need to record a macro which involves a substitution using a complex regex:

  1. create the regex with the aid of incremental search ('incsearch'), and using highlight search results ('hlsearch') to ensure that I'm matching the correct text
  2. create the substitution command with s/<c-r>//<replacement>, so I end up with s/<complete regex>/<replacement>
  3. start recording a macro, do some stuff, repeat the substitution with :upENTER (or @:or :Ctrl+r:ENTER), add the end steps and stop recording the macro.

The problem with this approach is that the macro stops working as soon as I use another ex command.

I could copy the : to another register and use it on the macro, but then it is necessary to keep avoiding to overwrite that register.

Currently I'm copying the substitution command on a split window an re-typing it, but certainly there must be a less cumbersome solution.

1 Answer 1

4

Edit: Better answer -

After you search you can do a :let @z = @/. This will copy your complex regex into register z. You can now freely use <C-r>z in your macro without having to retype the regex into your document.

I also realize that you said you didn't want to have worry about overwriting a register. Fun fact: the registers you use for macros are actually the same registers that you can yank to. So you could:

  • Record your macro, say to register q, using <C-r>/ to input your search pattern
  • Do "qp to see your macro written out
  • Delete the resulting ^R/ and replace it with the actual text from your search pattern. (Again using <C-r>/ to avoid typing it.)
  • Do a "qdd to then copy the new macro back to register q
  • Use @q as needed

Now at least you're only using one register to store the macro, and you don't have to actually reference any other ones.

Old answer:

Is there anything wrong with writing out <complexregex>, yanking it to a register that you don't use very often (Let's say z), and then using <C-r>z in your macro?

Workflow:

  • Type out regex
  • Visually select
  • Delete to register z: "zd
  • Record macro, something like: qq:s/<C-r>z/foo/^Mq
  • Use macro as needed: @q
5
  • The problem with copying the substitute command or the regex on another register is (as noted on the question) the need to avoid using that register again. If I record a macro and use the z register as auxiliary, and them start recording another macro, I have to remember to check if the previously recorded macro used some auxiliary register. This get out of hand if you need to record a third or fourth macro, thus it is still better to retype the command.
    – mMontu
    Jun 9, 2016 at 21:47
  • @mMontu Yes, I saw that after I posted. Sorry I'll try to read more thoroughly in the future. I've updated my answer with a possible workaround.
    – Tumbler41
    Jun 9, 2016 at 21:59
  • You can always store the pattern in a variable, e.g. :let search=@/, and insert that into your macro with ^R=search<CR>.
    – Antony
    Jun 9, 2016 at 22:01
  • @Antony @Tumbler41 Thanks for the ideas! Both are better than retyping. But I still believe there is something more direct (such as improved ^R<register> which inserts the register contents) or an improved workflow. This task seems to be common enough to have an easier solution.
    – mMontu
    Jun 9, 2016 at 22:29
  • Well, I wouldn't class this solution as difficult: you're just giving the search register an alternative name, and referring to that in the macro. You can create mappings for saving and inserting the search pattern if that helps.
    – Antony
    Jun 9, 2016 at 23:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.