7

I've noticed that vim's fold method affects the efficiency of autocomplete, e.g. C-N is slow, and C-X L is hideously slow in medium sized files with relatively expensive foldexprs.

I can't see the value in having foldexpr consulted while running through auto completes, so would like to disable this somehow so I get usable autocomplete back.

Any suggestions?


EDIT: Test case

A test case: No plugins; and only this, which must be the most minimal foldexpr function possible (and is completely useless, except for counting invocations) in .vimrc:

let g:c = 0 
function! Myfoldexpr() 
   let g:c = 1 + g:c 
   return '0' 
endfunction

Now start vim with a blank document. We'll copy the first 100 lines of Vim's own help file, and then run autocomplete line, choosing the 10th suggestion, then see how many times foldexpr was called.

:help
y100j:q
P:set foldexpr=Myfoldexpr()
:set fdm=expr
O<C-X><C-L><C-L><C-L><C-L><C-L><C-L><C-L><C-L><C-L><C-L><Esc>
:echo g:c
2088

Now that's a 100 line file, with relatively short lines and the foldexpr was called 2088 times (although 100 of these are done when first setting the foldexpr). Efficient foldexpr is obviously good, but we programmers ask a lot of our foldexpr, so they are necessarily non-trivial, and when their execution time is multiplied by several thousand it makes you choose between autocomplete or indent for productivity. Being greedy/lazy I'd like to be able to use both! Beyond attempting to rewrite several pretty well established foldexpr-based folding plugins (I've tried rewriting php-folding and after days of trying to optimise it to a workable state I gave up on foldexpr for php), perhaps there's a way to use a mapping to turn fdm=manual before autocomplete or some such?

  • Have you considered posting to the vim_dev list? – lcd047 Apr 30 '15 at 10:05
  • I'll post anything useful back here, but here's the vim_dev list posting – artfulrobot May 1 '15 at 13:00
  • I think your test case is wrong. If I make a test file, and add some text (by just doing iHello<Esc>, the g:c variable is also increased to 20, then doing oWorld<Esc> makes it 38 ... So the number of evaluations foldexpr seems unrelated to using completion... Try loading Vim with a minimal vimrc file and see if the problem still occurs, it could be another setting or a plugin. – Martin Tournoij May 1 '15 at 15:56
  • "I can't see the value in having foldexpr consulted while running through auto completes, " well, you're inserting text; so Vim needs to re-calculate which lines to fold. – Martin Tournoij May 1 '15 at 16:10
  • The test case is deliberately stupid, returning =. But just from the order of magnitude you can see something is up. On 2nd comment, Yeah, but I think it should do that at the end of an insert candidate (like it does for p), I think what it's doing is doing it per character of the insert candidate. – artfulrobot May 1 '15 at 16:21
4

I had a problem a while back with syntax folding PHP where typing { would interfere with subsequent folds until I typed the corresponding closing }. I found a suggestion somewhere (I think it was on the Vim Wiki) to temporarily set the foldmethod to manual while in insert mode. I don't know if this is à propos enough to make an answer rather than a comment, but code in comments is discouraged and possibly you can adapt it for your circumstances. Here are the two relevant lines from my .vimrc.

autocmd InsertEnter * if !exists('w:last_fdm') | let w:last_fdm=&foldmethod | setlocal foldmethod=manual | endif
autocmd InsertLeave,WinLeave * if exists('w:last_fdm') | let &l:foldmethod=w:last_fdm | unlet w:last_fdm | endif
2

perhaps there's a way to use a mapping to turn fdm=manual before autocomplete or some such?

Well, this does that:

inoremap <C-x> <Esc>:setlocal foldmethod=manual<CR>a<C-x>
autocmd CompleteDone * :setlocal foldmethod=expr
autocmd InsertLeave * :setlocal foldmethod=expr

We remap <C-x> to first set the foldmethod to manual before calling <C-x>, and with the CompleteDone and InsertLeave autocommands we reset it to expr.

I tested this by pressing <C-l> 11 times; my g:c values:

  • After Vim startup: 202
  • With this hack: 408
  • Without this hack: 2130

As I've said in the comments: this hack shouldn't be required. You mentioned "relatively expensive foldexprs", I suspect that this is the real problem; I can't be sure of course, because you didn't post your foldexpr, but I think it's worth asking a new question about this ("How can I make this foldexpr faster?").

  • Thanks, will try this. As for specific foldexpr see github.com/tmhedberg/SimpylFold for python, and github.com/swekaj/php-foldexpr.vim for php. But yes, we both agree that's another question! – artfulrobot May 1 '15 at 18:32
  • @artfulrobot The Python foldexpr is also quite slow for me... I'm not sure this can be improved on in this specific case, so this work-around might be best here :-/ Not sure why the PHP foldexpr is required? Can't the syntax file do that (this is usually faster) – Martin Tournoij May 1 '15 at 18:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.