vim-repeat icon indicating copy to clipboard operation
vim-repeat copied to clipboard

Can't repeat surround.vim action with . after undoing with u

Open michelesr opened this issue 2 years ago • 1 comments

Steps to reproduce:

  1. use a surround.vim action such as csi"
  2. try to repeat with . multiple times (it works)
  3. now press u to undo last repeat
  4. press . again: now repeat doesn't work correctly, and it's likely to repeat last vim native atomic operation

michelesr avatar Dec 26 '22 15:12 michelesr

I just stumbled over this issue myself and I think I found the problem: it's a race condition between the plugin and feedkeys().

In this line, vim-repeat feeds the undo command into the vim typeahead buffer via feedkeys(). The function documents that it does not wait until the appended command has actually been handled, but instead it returns immediately.

Once returned, the plugin updates g:repeat_tick to the latest change value in this line. Only after that does vim handle the undo command, which updates the buffer tick again and brings it out of sync with g:repeat_tick. Thus, the plugin no longer knows that its command is still up-to-date.

There are two solutions to this issue. One is to pass the mode 'nx' instead of 'n' to feedkeys(). The x tells it to immediately empty the typeahead buffer and only return when that is done. This way, when g:repeat_tick is updated, it actually receives the latest value.

The other solution works on older vim versions as well and requires to add a single-use autocmd TextChanged <buffer> let g:repeat_tick = b:changedtick after the feedkeys() call. It's been implemented in this PR.

broken-pen avatar May 08 '23 13:05 broken-pen