Closed kiryph closed 7 years ago
The plugin FastFold resolves this issue which is apparently a problem of vim itself. :h vimtex-folding
mentions already FastFold
. However, IMHO it is not obvious that a plugin such as vim-commentary
is affected by this (most likely due to insert mode updates of folds).
Unfortunately, the plugin vim-fold-cycle which I use for my customized mappings of zC
, zo
, and zc
(see here https://github.com/arecarn/vim-fold-cycle/issues/6#issuecomment-294370249) does not support FastFold
.
Another solution could be to set temporarily foldmethod
to manual for vim-commentary
mappings and return afterwards to the old value. I am not sure how to do this.
Related question is https://stackoverflow.com/questions/21280457/stop-vim-from-dynamically-updating-folds
Note that neovim
does not have this issue (most likely due to following change https://github.com/neovim/neovim/commit/9d4fcec7c6b65ef04fd4416b014e96f33b1f708a).
There is also a pending pull request for vim (https://github.com/vim/vim/pull/1045). However, I cannot confirm that it helps in this circumstance by following steps:
brew edit vim
; change head "https://github.com/vim/vim.git"
to head "https://github.com/Shougo/vim.git", :branch => 'fold'
brew reinstall vim --HEAD
Profiling returns:
FUNCTIONS SORTED ON TOTAL TIME
count total (s) self (s) function
1 14.207625 0.059748 <SNR>27_go()
11540 14.147601 1.397272 vimtex#fold#level()
3955 5.983754 5.983048 123()
3835 5.753792 0.027972 143()
3835 5.725820 144()
4965 0.273035 0.193778 136()
6395 0.210174 151()
5765 0.186866 148()
6275 0.128953 131()
4965 0.124612 133()
4965 0.089143 141()
4965 0.079257 139()
1 0.000960 <SNR>28_UpdateCommentString()
160 0.000706 129()
10 0.000500 0.000289 LightlineFilename()
10 0.000421 0.000362 LightlineMode()
1 0.000320 0.000112 <SNR>100_cursormoved_delayed_cb()
15 0.000247 LightlineFileencoding()
10 0.000246 LightlineFugitive()
10 0.000208 <SNR>27_strip_white_space()
FUNCTIONS SORTED ON SELF TIME
count total (s) self (s) function
3955 5.983754 5.983048 123()
3835 5.725820 144()
11540 14.147601 1.397272 vimtex#fold#level()
6395 0.210174 151()
4965 0.273035 0.193778 136()
5765 0.186866 148()
6275 0.128953 131()
4965 0.124612 133()
4965 0.089143 141()
4965 0.079257 139()
1 14.207625 0.059748 <SNR>27_go()
3835 5.753792 0.027972 143()
1 0.000960 <SNR>28_UpdateCommentString()
160 0.000706 129()
10 0.000421 0.000362 LightlineMode()
10 0.000500 0.000289 LightlineFilename()
15 0.000247 LightlineFileencoding()
10 0.000246 LightlineFugitive()
10 0.000208 <SNR>27_strip_white_space()
15 0.000194 LightlineFiletype()
I do not know that much about why or why not vim-commentary do not support FastFold, and I can not immediately give a solution for your issue with it. However, I can confirm that expression based folding is slow, and that there is unfortunately little I can do about it. I've tried to make the folding function as efficient as possible, and I am not surprised if I could make it even faster. However, I do not see how at the moment. Pull requests or suggestions are very welcome!
In the meantime, I heartily recommend that you either use FastFold, or that you use the manual folding and explicitly use zx
to refresh, see :h vimtex_fold_manual
.
Yes, it is an issue of commentary or actually vim. With my last profiling test there were 11540 invocations of foldexpr
. It does not make sense to optimize vimtex foldexpr as long as there are unnecessary calls to it. If it then vimtex#foldexpr is too slow it can be reported to you and one can start thinking about it.
This means for me either:
neovim
,fastfold
and stopping to use vim-fold-cycle
, Thanks anyhow.
If it helps, I've switched to neovim and I'm happy I did. I have, so far, had no issues with it, and it feels smoother and "cleaner".
In any case, thanks for your input on the issue. I hope Bram will fix the unnecessary calls to foldexpr, as I think that would help a lot of Vim users in general.
Explain the issue
When commenting/uncommenting code blocks, I often use the mapping
gcip
from vim-commentary. However, when using this in a complex latex file with extensive folding, this becomes incredibly slow.Minimal working example
Cursor in line 62.
Minimal vimrc file
Close all folds with
zM
, move cursor with:62
,zv
to reveal cursor and start profiling with:profile start output.log
and:profile func *
. Then pressgcip
andu
on line 62 and have a look into theoutput.log
. The summary on my system looks as following:CLICK HERE FOR FULL PROFILING REPORT
``` FUNCTION 1() Called 4 times Total time: 0.000098 Self time: 0.000098 count total (s) self (s) 4 0.000009 if s:delayed_show.show_timer 4 0.000014 call timer_stop(s:delayed_show.show_timer) 4 0.000004 endif 4 0.000006 if s:delayed_show.hide_timer call timer_stop(s:delayed_show.hide_timer) call s:delayed_show.hide_cb(s:delayed_show.hide_timer) endif 4 0.000020 let s:delayed_show.show_timer = timer_start(g:matchparen_show_delay, s:delayed_show.show_cb) 4 0.000017 let s:delayed_show.show_pos = getpos('.') FUNCTION 2() Called 2 times Total time: 0.000704 Self time: 0.000262 count total (s) self (s) 2 0.000057 if s:delayed_show.show_pos == getpos('.') 2 0.000589 0.000147 call s:Highlight_Matching_Pair() " If something was highlighted, start a timer to hide it. 2 0.000014 if exists('w:paren_hl_on') && w:paren_hl_on if s:delayed_show.hide_timer call timer_stop(s:delayed_show.hide_timer) endif let s:delayed_show.hide_timer = timer_start(g:matchparen_hide_delay, s:delayed_show.hide_cb) endif 2 0.000002 endif FUNCTION vimtex#util#in_syntax() Called 2 times Total time: 0.000639 Self time: 0.000639 count total (s) self (s) " Usage: vimtex#util#in_syntax(name, [line, col]) " Get position and correct it if necessary 2 0.000013 let l:pos = a:0 > 0 ? [a:1, a:2] : [line('.'), col('.')] 2 0.000005 if mode() ==# 'i' let l:pos[1] -= 1 endif 2 0.000015 call map(l:pos, 'max([v:val, 1])') " Check syntax at position 2 0.000593 return match(map(synstack(l:pos[0], l:pos[1]), "synIDattr(v:val, 'name')"), '^' . a:name) >= 0 FUNCTION neomake#GetCurrentErrorMsg() Called 2 times Total time: 0.000205 Self time: 0.000205 count total (s) self (s) 2 0.000019 let buf = bufnr('%') 2 0.000010 let ln = line('.') 2 0.000008 let ln_errors = [] 6 0.000024 for maker_type in ['file', 'project'] 4 0.000046 let buf_errors = get(s:current_errors[maker_type], buf, {}) 4 0.000033 let ln_errors += get(buf_errors, ln, []) 4 0.000010 endfor 2 0.000010 if empty(ln_errors) 2 0.000006 return '' endif if len(ln_errors) > 1 let ln_errors = copy(ln_errors) call sort(ln_errors, function('neomake#utils#sort_by_col')) endif let entry = ln_errors[0] let r = entry.maker_name . ': ' . entry.text let suffix = entry.type . (entry.nr != -1 ? entry.nr : '') if !empty(suffix) let r .= ' ('.suffix.')' endif return r FUNCTIONApparently the problematic function is
vimtex#fold#level()
which is evaluated 2604 times and results in 0.42sec. When there are more folds, this gets even worse (several seconds).using tcomment instead of commentary.vim, nothing changes and the summary is
CLICK HERE FOR FULL PROFILING REPORT
``` FUNCTION