You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I think I have an explanation for what is happening.
This can happen for other plugins. The conditions are:
A plugin calls repeat#set and doesn't move the cursor after it does.
Without moving the cursor, some other operation that is repeatable moves the cursor. 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:
User invokes the <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.
User invokes ofoo<Esc>.
The cursor has moved, so g:repeat_tick is updated afterofoo<Esc>.
The user invokes dot-repeat. In 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.
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!The text was updated successfully, but these errors were encountered: