tpope / vim-repeat

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

Fix open fold after undo #81

Closed lacygoill closed 4 years ago

lacygoill commented 4 years ago

This PR tries to fix the issue #80.

lacygoill commented 4 years ago

Actually, the simplest and most reliable fix is to just get rid of zv, and pass the t flag to feedkeys(), so that the u key is not processed as if it came from a mapping. Is there a reason why the t flag was not used originally? Is it because it was not implemented at the time the plugin was written? It works on v7.3.001.

diff --git a/autoload/repeat.vim b/autoload/repeat.vim
index 708c318..86233f1 100644
--- a/autoload/repeat.vim
+++ b/autoload/repeat.vim
@@ -131,8 +131,7 @@ endfunction

 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' : '')
+    call feedkeys((a:count ? a:count : '').a:command, 'nt')
     if preserve
         let g:repeat_tick = b:changedtick
     endif

If you want me to push a new commit, let me know.

tpope commented 4 years ago

That reason is correct, and while 7.3 is ancient history at this point, I still try not to break Vim backwards compatibility without a good reason. A simple v:version >= 703 ? 'nt' : 'n' would satisfy my requirements.

lacygoill commented 4 years ago

Actually, the t flag causes another issue. During a recording, t would cause the undo command to be recorded twice. So the original fix was probably better.

lacygoill commented 4 years ago

I'm closing the PR because the proposed fix causes another issue; it prevents u, U, and C-r from printing some info about the undo state, as reported in #27.

One solution would be to install a one-shot autocmd listening to TextChanged, which would execute zv only on the condition that the cursor is inside a closed fold:

diff --git a/autoload/repeat.vim b/autoload/repeat.vim
index 708c318..1db2b86 100644
--- a/autoload/repeat.vim
+++ b/autoload/repeat.vim
@@ -132,10 +132,12 @@ endfunction
 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
+    au TextChanged <buffer> ++once if &foldopen =~# 'undo\|all' && foldclosed('.') != -1
+        \ |     call feedkeys('zv', 'in')
+        \ | endif
 endfunction

 nnoremap <silent> <Plug>(RepeatDot)      :<C-U>exe repeat#run(v:count)<CR>

But I think this patch would cause a merge conflict with the one proposed in #79. If the latter is merged, I think I could then suggest a patch fixing the issue.

Also, note that ++once is fairly recent (8.1.1113), but it can be emulated by wrapping the autocmd inside an augroup, and making it clear itself when triggered.

Anyway, for anyone interested, here is my current fix on the fork I'm using.