Open glts opened 10 years ago
I think I have an explanation for what is happening.
This can happen for other plugins. The conditions are:
repeat#set
and doesn't move the cursor after it does.repeat#set
must not be called by this operation.Result: The next time .
is invoked, vim will repeat the plugin on stage (1), instead of the operation on stage (2).
What is happening?
@glts is right. It does have something to do with CursorMoved
.
In short, g:repeat_tick
is updated after (2) instead of in (1), because that is when CursorMoved
event first occurs. This prevents vim-repeat in repeat#run
from knowing (2) ever took place.
Detailed example:
<Plug>TransposeCharacters
.repeat#set
sets up an autocmd to update g:repeat_tick
on CursorMoved
event (code). The example plugin doesn't move the cursor after repeat#set
is called, so the autocommand is not executed yet.ofoo<Esc>
. g:repeat_tick
is updated after ofoo<Esc>
.repeat#run
vim-repeat sees that g:repeat_tick == b:changedtick
(code), concludes that the last operation was the plugin, instead of the last insert, and repeats it.Another example where this would happen is with tpope/vim-unimpaired, but only if the cursor is first placed on the first non-blank character. Then: ]<Space>ofoo<Esc>.
will add a blank line instead of a foo line. (It may seem like an artificial edge case, but that is what got me into this bug hunt.)
Possible Solution
The easiest solution that I can think of is to separate repeat#set
into two different functions, one that sets up the autocommand and one that doesn't. The latter should be used in cases where the plugin does not pend on a motion to complete.
The drawbacks are that it complicates vim-repeat's API, and doesn't provide an automatic fix where vim-repeat is already used.
Maybe there is a solution that doesn't require a new function, but I don't see it right now.
Any thoughts?
I was trying the mapping from Vimcasts episode 61.
After running the mapping
cp
, repeating it.
, and making another changeofoo<Esc>
, the.
becomes ineffective. It doesn't repeatofoo<Esc>
.If this is a fundamental limitation of repeat.vim (
CursorMoved
...?) I believe it should be mentioned in the docs. Thanks!