Give this a try. It remaps
@ so that
g@ (plus a dummy motion
l) is used afterwards, thus becoming the last operator and subject to repeating with
" When . repeats g@, repeat the last macro.
" If no count is supplied use the one saved in s:atcount.
" Otherwise save the new count in s:atcount, so it will be
" applied to repeats.
let s:atcount = v:count ? v:count : s:atcount
" feedkeys() rather than :normal allows finishing in Insert
" mode, should the macro do that. @@ is remapped, so 'opfunc'
" will be correct, even if the macro changes it.
" Called by g@ being invoked directly for the first time. Sets
" 'opfunc' ready for repeats with . by calling AtSetRepeat().
" Make sure setting 'opfunc' happens here, after initial playback
" of the macro recording, in case 'opfunc' is set there.
" Enable calling a function within the mapping for @
nno <expr> <plug>@init AtInit()
" A macro could, albeit unusually, end in Insert mode.
ino <expr> <plug>@init "\<c-o>".AtInit()
let s:atcount = v:count1
let c = nr2char(getchar())
nmap <expr> @ AtReg()
I've tried to handle as many corner cases as I can think of. You can
.. Counts to
. are retained for subsequent
This is tricky, and I'm not convinced that something won't break
somewhere along the way. So no guarantees, warranties, or promises with
Personally, I'm okay having a difference between the fine-grained
. for the last change, and the macro repeats of
I figured, having gone this far, that I may as well add some additional code that will allow pressing
after recording a macro to play it back.
nno <expr> <plug>qstop QStop()
ino <expr> <plug>qstop "\<c-o>".QStop()
let s:qrec = 0
if s:qrec == 1
let s:qrec = 0
let s:qreg = nr2char(getchar())
if s:qreg =~# '[0-9a-zA-Z"]'
let s:qrec = 1
nmap <expr> q QStart()