From ab448910a54861542249931af95845bbd5c6a39f Mon Sep 17 00:00:00 2001 From: Jaehwang Jung Date: Thu, 8 Jun 2023 19:08:01 +0900 Subject: [PATCH] fix: use win_execute() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * The current implementation of `s:WinDo()` fails at avoiding some side effects. Specifically, `:windo` and `:wincmd w` trigger `CursorMoved` even if `noautocmd` is used (both in Vim and Nvim ≥ 0.10). So use `win_execute()` if it's available. * With `win_execute()`, setting fdm itself doesn't seem to trigger recomputation of fold. Querying the foldlevel seems to be sufficient for triggerring fold recomputation. --- plugin/fastfold.vim | 63 ++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/plugin/fastfold.vim b/plugin/fastfold.vim index d0d5d6b..b08356b 100644 --- a/plugin/fastfold.vim +++ b/plugin/fastfold.vim @@ -68,33 +68,42 @@ function! s:LeaveWin() endif endfunction -" Like windo but restore the current buffer. -" See http://vim.wikia.com/wiki/Run_a_command_in_multiple_buffers#Restoring_position -function! s:WinDo( command ) - " avoid errors in CmdWin - if exists('*getcmdwintype') && !empty(getcmdwintype()) - return - endif - " Work around Vim bug. - " See https://groups.google.com/forum/#!topic/vim_dev/LLTw8JV6wKg - let curaltwin = winnr('#') ? winnr('#') : 1 - let currwin=winnr() - if &scrollopt =~# '\' - set scrollopt-=jump - let l:restore = 'set scrollopt+=jump' - endif - " Work around Vim bug. - " See https://github.com/vim/vim/issues/4622#issuecomment-508985573 - let l:currwinwidth = &winwidth - let &winwidth = &winminwidth > 0 ? &winminwidth : 1 - silent! execute 'keepjumps noautocmd windo ' . a:command - silent! execute 'noautocmd ' . curaltwin . 'wincmd w' - silent! execute 'noautocmd ' . currwin . 'wincmd w' - if exists('l:restore') - exe l:restore - endif - let &winwidth = l:currwinwidth -endfunction +" Like :windo, but restores the current window and avoids side effects. +if exists('*win_execute') + function! s:WinDo( command ) + for w in range(1, winnr('$')) + " query foldlevel to trigger recomputation of folds + call win_execute(win_getid(w), a:command . ' | if !s:Skip() | call foldlevel(1) | endif', 'silent!') + endfor + endfunction +else + " See http://vim.wikia.com/wiki/Run_a_command_in_multiple_buffers#Restoring_position + function! s:WinDo( command ) + " avoid errors in CmdWin + if exists('*getcmdwintype') && !empty(getcmdwintype()) + return + endif + " Work around Vim bug. + " See https://groups.google.com/forum/#!topic/vim_dev/LLTw8JV6wKg + let curaltwin = winnr('#') ? winnr('#') : 1 + let currwin=winnr() + if &scrollopt =~# '\' + set scrollopt-=jump + let l:restore = 'set scrollopt+=jump' + endif + " Work around Vim bug. + " See https://github.com/vim/vim/issues/4622#issuecomment-508985573 + let l:currwinwidth = &winwidth + let &winwidth = &winminwidth > 0 ? &winminwidth : 1 + silent! execute 'keepjumps noautocmd windo ' . a:command + silent! execute 'noautocmd ' . curaltwin . 'wincmd w' + silent! execute 'noautocmd ' . currwin . 'wincmd w' + if exists('l:restore') + exe l:restore + endif + let &winwidth = l:currwinwidth + endfunction +endif " WinEnter then TabEnter then BufEnter then BufWinEnter function! s:UpdateWin()