Re: foldmethod=expr very slow

2006-07-26 Thread Cory Echols

On 7/26/06, Thore B. Karlsen [EMAIL PROTECTED] wrote:

  set foldexpr=GetFoldLevel()

  function! GetFoldLevel()
let line_text = getline(v:lnum)

let left_idx = (stridx(line_text, '{') = 0)
let right_idx = (stridx(line_text, '}') = 0)

if left_idx
  if ! right_idx
return 'a1'
  endif
elseif right_idx
  return 's1'
endif

return '='
  endfunction

I spoke too soon. I tested it on another file that is 2500 lines long,
and it is still unbearably slow. It gets worse towards the end of the
file, where it can still take seconds for characters to show up when I
type them. I think I'll have to fire up vim in a profiler to see what
is causing this slowness, because if this system can compress dozens
of channels of video in realtime without breaking a sweat it seems
strange that inserting a character in a smallish text file would be a
problem.


Use of return values like 'a1', 's1' and '=' in a fold expression will
cause significant slowdown.  This is because vim has to recursively
evaluate the fold expression for many lines every time the folding is
recalculated.  Since your expression returns nothing other than these
particular values, it probably has to run the expression on *every*
line in your file.

I tried experimenting with folding expressions for c# a while back.  I
found that I had to return real number values for as many lines as
possible.  (Even when it wasn't necessary for correctness).  This gave
absolute fold levels for many lines and limited the recursive
evaluation that vim had to use in situations where I had to return an
'a1', 's1' or '='.  This was the only way I could get acceptable
performance.


Re: foldmethod=expr very slow

2006-07-26 Thread Cory Echols

On 7/26/06, Thore B. Karlsen [EMAIL PROTECTED] wrote:

On Wed, 26 Jul 2006 11:16:31 -0400, Cory Echols [EMAIL PROTECTED]
wrote:
Use of return values like 'a1', 's1' and '=' in a fold expression will
cause significant slowdown.  This is because vim has to recursively
evaluate the fold expression for many lines every time the folding is
recalculated.  Since your expression returns nothing other than these
particular values, it probably has to run the expression on *every*
line in your file.

Yes, I understand that. However, when I'm editing a line I would
expect vim to have cached the fold levels of the surrounding lines,
but it seems to reevaluate all the lines above it for every keypress.
One would think everything should stay the same until something
entered on the current line caused a change in the fold level.

In other words, I would expect vim to continuously evaluate the
foldexpr on the current line for every character I typed, and not do
anything else until the fold level changed.


I once wrote a foldexpression that kept track of the number of times
it was evaluated.  I don't remember the exact numbers, but I was
astounded by the number of times it was executed for each keystroke.


When I open the file, it opens instantly. I can navigate around the
file just fine, and open/close folds. It seems to me that there is
something strange about the way the foldexpr seems to be constantly
reevaluated when I'm typing.


I'm suprised the file opens so quickly.  Opening the file was where my
expressions were still unacceptably slow.  Even so, I'll bet we're
more tolerant of delays while opening that we are of delays between
insert-mode keystrokes.


I tried experimenting with folding expressions for c# a while back.  I
found that I had to return real number values for as many lines as
possible.  (Even when it wasn't necessary for correctness).  This gave
absolute fold levels for many lines and limited the recursive
evaluation that vim had to use in situations where I had to return an
'a1', 's1' or '='.  This was the only way I could get acceptable
performance.

How do you do your folding? I'm not sure how I could do that the way I
like to do my folding. :( Maybe I'll resort to just modifying the vim
source to change the way foldmethod=marker works.


I pretty much gave up on the idea of nested folds.  I decided that I
would only fold method bodies at level 1.  This gave me lots of
shortcuts for keywords that only appeared inside method bodies (so my
expression could return '1' for those lines).  I might post my code,
but it's verbose and very much overkill because it contains many
functions that I hoped would be useful for more general c# editing.