tpope / vim-repeat

repeat.vim: enable repeating supported plugin maps with "."
http://www.vim.org/scripts/script.php?script_id=2136
2.58k stars 81 forks source link

feedkeys in undo sometimes doesn't finish, destroying further repeats #88

Closed orlp closed 3 years ago

orlp commented 3 years ago

In this plugin there's the following function that gets used to implement undo, plus one debug line I added.

function! repeat#wrap(command,count)
    let preserve = (g:repeat_tick == b:changedtick)
    call feedkeys((a:count ? a:count : '').a:command, 'n')
    exe (&foldopen =~# 'undo\|all' ? 'norm! zv' : '')
    if preserve
        let g:repeat_tick = b:changedtick
    endif
    echom g:repeat_tick b:changedtick preserve " Debug.
endfunction

With some functions (I find it difficult to make a minimal reproducible example, it shows up in a plugin I'm making) that use cgn internally the feedkeys call in the above does not 'finish'. It's being lazy.

That means that

echom g:repeat_tick b:changedtick preserve " Debug.

prints something like 15 15 1, but manually inspecting b:changedtick again after the mapping has resolved gives 17.

I fixed it in a local fork by changing

call feedkeys((a:count ? a:count : '').a:command, 'n')

to

call feedkeys((a:count ? a:count : '').a:command, 'nx')

to force the feedkeys call to do its work eagerly rather than lazily.

I don't know whether that negatively impacts others using this plugin, but for me it was necessary to get correct undo/redo behavior.

orlp commented 3 years ago

Oh, dupe of https://github.com/tpope/vim-repeat/issues/63#issue-323810749.