39

I'm using complex repeats to record my operations (qq to record, some operations, q to stop) and I did a mistake.

It is possible to see what I've recorded and correct the mistake, instead of doing it again?

Invoking recorded characters by @q works, but I can't see it in my mappings (:map q - No mapping found).

And there is not much information in help by typing: :help recording.

42

Note: I'm assuming you're using the a register for the entirety of this answer, but you can use any register

Note2: <1b> is Esc; you can insert this with Ctrl+v and then Esc. It may also show up as ^[ (depending on the display setting).


It's not a mapping; so it makes sense that :map doesn't work. It's recorded in a register, and you can see & edit it like any register.

All that q does is "clear this register, and append any keystroke to it", and all that @ does is "evaluate a register as commands".

There is nothing "different" about a macro, you can invoke any register as a macro.


To view just use:

:echo @a

Just like any register.

You can also use :registers to view all registers.


To edit you can do several things:

The simplest way you be to just assign to @a, like so:

:let @a='iasd<1b>'

This will start insert mode (i), insert asd, and Escape back to normal mode.

This isn't very useful for extensive editing; you could use functions (ie. substitute()), or maybe appending something (:let @a=@a . 'more'), but changing something in the middle isn't that easy.

I've found that the best way for this, is to start a new buffer with :split or :tabnew and edit the register by inserting it there, editing it, and then copying it back.

You can use "ap which will insert the text in the buffer (where a is your register):

iThis is A<1b>

Now I can just change the line to maybe:

iThis is an edited macro<1b>

Then I do ^v$"ay to yank (copy) this line to the a register:

  • ^ for start of line
  • v for visual mode
  • $ for end of line
  • "ay yank the selection to register a

If you wish, you can do this without using visual mode with ^"ay$.

You can now use @a, as if this is what you originally recorded.

You can also just use yy, and then @", which is a bit faster. This will also copy the trailing newline, though, and may cause side-effects... Another way to make this faster is to use a macro :-)

  • 2
    I would note that yanking a linewise motion into your register will have a side effect of including a newline character, as if you had pressed Enter at the end of your recording. In many cases this might be benign, but in scenarios where you've carefully crafted the cursor position at the end of the recording, it can affect the repeatability. – tommcdo Feb 13 '15 at 13:53
  • @tommcdo Right; you can just use v and select the entire line (without the newline). – Martin Tournoij Feb 13 '15 at 14:16
  • @Carpetsmoker "v^$"ay to yank (copy) this line to the a register." Shouldn't that ^ come before the v, and with $ aren't you still copying the newline? I think it should be: 0v$h"ay (yes painfully long!) – joeytwiddle Feb 24 '15 at 22:39
  • 2
    @joeytwiddle no, $ moves to the end of the line, but doesn't include the newline. It's the difference between 0y$ and yy. Putting h after the $ would just mean that you'd miss the last character. – evilsoup Feb 28 '15 at 11:10
  • One thing you can do to make editing :let @a= type commands more easily editable is to type : <Ctrl-f>, select and edit the line concerned (the last line, which it defaults to, if you're editing the last line you entered) using vim as usual. Hit return when you're done to execute the line, or <Ctrl-c> to exit. – user859 Oct 22 '15 at 11:57
9

To get something to work with...

qajjjq

Will start record a macro into the a register.

You can see many of your current registers (used for macros, yanking, deleting, etc.) with the :reg command, or you can specify a register to display by providing its name. For example, to show register a:

:reg a

yields

--- Registers ---
"a   jjj

You can append to an existing named register by using the corresponding capital letter. This works not just for recording macros, but for yanking as well. For example:

qAkkkq
:reg a

yields

--- Registers ---
"a   jjjkkk

If you want to use the let syntax to edit an existing macro, you can do:

let @a='<C-r>a'

which will expand to

let @a='jjjkkk'

and you can then change the individual keystrokes.

Note that you can use the <C-r> (that is, control + r) to paste from any register into command-line mode (or in insert mode, for that matter).

Furthermore, when you are in command-line mode, if you type <C-f> this will pop up the command-line window, in which you can see/edit past commands issued, and you can edit your current command before calling it. Press enter on the command you want to submit.

The benefit of this is that you can use your normal movement/substitution commands inside this buffer to edit your macro. For example:

let @a='<C-r>a'<C-f>

will bring up:

:118 reg
:119 reg a
:120 let @a='jjjkkk'

If you're on command 120, you can do:

s/kkk/}
<return>
:reg a

yields

--- Registers ---
"a   jjj}

You can, of course, paste the contents of the register into your buffer, and change it there. But you can do everything you need to without contaminating your working buffer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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