Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my macro stop at the end of file

Tags:

vim

I write a macro which adds a ; at the end of line and moves the cursor to next line. And I repeatly run this macro to add ;s to every line of the buffer.

Here is my input

qaA;ESCjq
1000@a

And here is my question. My file has only 5 lines, and I repeat the macro 1000 times. It should add a lot of ;s at the end of the last line, but what vim does is just stopping at the end of file. I want to know which mechanism in vim leads to this.

I believe it's a simple question, but I just cannot find any official doc to prove it. So I hope there are some doc that describe this mechanism formally.

like image 318
Lotus Avatar asked Oct 26 '25 14:10

Lotus


1 Answers

In short…

  • j moves the cursor down one line.
  • This is impossible to do when the cursor is on the last line so Vim throws an error.
  • Your macro stops being executed because of that error.

AFAIK, this is not documented in a very straightforward way. :help 10.1 is completely silent about error handling and :help @ is not really helpful either:

[…]
The register is executed like a mapping, that means
that the difference between 'wildchar' and 'wildcharm'
applies, and undo might not be synced in the same way.
[…]

That passing reference to mappings is the only line we can follow and, without a proper tag, it's a tiny one.

Anyway, only after a tentative :help mapping and a lot of scrolling do we get to the bottom of it:

                                                        *map-error*
Note that when an error is encountered (that causes an error message or might
cause a beep) the rest of the mapping is not executed.  This is Vi-compatible.

Now, using a large [count] to make sure a macro is executed as many times as necessary without having to count is akin to brute force. Effective, sort of, but not very efficient.

A better way to use macros in this case would be to not include the motion in the recording:

qaA;<ESC>q

and play it back with :help :normal and a proper :help :range:

:%normal @a

But, frankly, why go through all that trouble when you can do:

:%s/$/;

?

like image 149
romainl Avatar answered Oct 29 '25 07:10

romainl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!