VIM: How to check whether the current script is running in a macro?

1

In a number of cases I have some vim script that I only want to execute when it is not being run in a macro. For example, in some cases I blink the cursor to remind myself where it is now (which is pointless when run in a macro, and just causes the macro to take 10x as long).

So for these cases I would like to check whether it is running as a macro, and avoid doing the unnecessary operation in this case. I scoured help for a bit but could not find a flag to detect this. Is this possible?

Steve Vermeulen

Posted 2013-11-04T00:17:47.063

Reputation: 517

How do you trigger the blinking? If it's a mapping, don't use it. If it's an autocmd, use an event that's not triggered during a macro like CursorHold. Or start every macro with a command that isables your blinking function temporarily. – romainl – 2013-11-04T07:06:27.877

Answers

2

There is no function like mode() or special v:macro_running variable, and many would argue that those would just encourage bad practices.

What you can do is use the behavior of feedkeys(), whose passed keys are usually executed right after the command / mapping, but only at the very end of the macro execution. If you put your long-running commands in there, they will directly slow down normal commands as usual, but only (cummulatively) slow down after the macro execution (and you can usually abort that with <C-C>).

Example

let @q = ',a,b'

Instead of:

nnoremap ,a aHello<Esc>2gs
nnoremap ,b aWorld<Esc>2gs

use

nnoremap ,a aHello<Esc>:call feedkeys('2gs', 'n')<CR>
nnoremap ,b aWorld<Esc>:call feedkeys('2gs', 'n')<CR>

This will immediately insert the whole HelloWorld text inside a macro.

Ingo Karkat

Posted 2013-11-04T00:17:47.063

Reputation: 19 513