How do I detect whether a macro is currently being recorded or executed in Vimscript?
Answer
reg_recording() and reg_executing()
Explanation
Vim exposes two built-in functions for querying the current macro state: reg_recording() and reg_executing(). Both return the register letter currently in use, or an empty string when no macro is active. These unlock a class of context-aware behavior — from real-time statusline indicators to mappings that change behavior mid-recording.
How it works
reg_recording()— returns the register letter whileq{reg}is active (recording); returns''otherwisereg_executing()— returns the register letter while@{reg}is running (executing); returns''otherwise- Both can be combined:
reg_recording() . reg_executing()gives the union of active macro state
Example
Add a recording indicator to your statusline so you always know when you're mid-macro:
set statusline+=%{reg_recording()!=''?'[REC @'.reg_recording().']':''}
With this, the statusline shows [REC @q] the moment you press qq, and clears automatically when you press q to stop.
For a mapping that skips an action during macro execution:
nnoremap <expr> <F5> reg_executing() == '' ? ':make<CR>' : ''
This prevents :make from firing if <F5> is embedded in a macro being replayed.
Tips
- Neovim users can also hook into
RecordingEnter/RecordingLeaveautocmd events (Neovim 0.8+) for event-driven alternatives mode(1)returns'R'during Ex recording but does not distinguish which register;reg_recording()is more precise- These functions work inside
statusline,tabline, and<expr>mappings — anywhere an expression is evaluated