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 Thore B . Karlsen
On Wed, 26 Jul 2006 11:16:31 -0400, Cory Echols [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.

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.

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 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.

-- 
Be seeing you.



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.


Re: foldmethod=expr very slow

2006-07-26 Thread Thore B . Karlsen
On Wed, 26 Jul 2006 14:05:45 -0400, Cory Echols [EMAIL PROTECTED]
wrote:

 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.

I just tried that, and my suspicions were confirmed. When in insert
mode, any keystroke will cause foldexpr to be evaluated for every line
above the current line.

 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.

That must be it. I can wait a second or two while the file is being
opened, but waiting a second or two between each keystroke when I'm
writing is too much.

[...]

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.

Well, I think I've found a solution that works for me. It turns out
that what was causing my problems was where vim interpreted a number
following a marker as a fold level. A line like this would mess up my
folds:

   int array[16] = {0};

In those cases it's easy enough to insert a space before the 0, but
there are cases where it's not that easy, or not desireable.

What I ended up doing was changing fold.c to not look for a fold level
after a marker, and recompiling. Now everything seems to work great,
and I don't notice any slowdown.

Perhaps there should be an option for not interpreting numbers after a
fold marker as a fold level, but I don't know if this is causing
enough people grief that it would be included. I'm happy with my quick
fix for now.

-- 
Be seeing you.



Re: foldmethod=expr very slow

2006-07-26 Thread Benji Fisher
On Wed, Jul 26, 2006 at 03:33:55PM -0500, Thore B. Karlsen wrote:
 
 Well, I think I've found a solution that works for me. It turns out
 that what was causing my problems was where vim interpreted a number
 following a marker as a fold level. A line like this would mess up my
 folds:
 
int array[16] = {0};
 
 In those cases it's easy enough to insert a space before the 0, but
 there are cases where it's not that easy, or not desireable.
 
 What I ended up doing was changing fold.c to not look for a fold level
 after a marker, and recompiling. Now everything seems to work great,
 and I don't notice any slowdown.
 
 Perhaps there should be an option for not interpreting numbers after a
 fold marker as a fold level, but I don't know if this is causing
 enough people grief that it would be included. I'm happy with my quick
 fix for now.

 I am surprised that {0} is recognized as a fold marker.  Do you
have 'foldmarker' set to the default value of {{{,}}} or something else?
In my limited tests (try zc in Normal mode and see whether vim throws an
error message) {0} is not recognized as a fold marker but {{{0}}} is.

HTH --Benji Fisher


Re: foldmethod=expr very slow

2006-07-26 Thread Thore B . Karlsen
On Wed, 26 Jul 2006 17:19:42 -0400, Benji Fisher
[EMAIL PROTECTED] wrote:

 Well, I think I've found a solution that works for me. It turns out
 that what was causing my problems was where vim interpreted a number
 following a marker as a fold level. A line like this would mess up my
 folds:
 
int array[16] = {0};
 
 In those cases it's easy enough to insert a space before the 0, but
 there are cases where it's not that easy, or not desireable.
 
 What I ended up doing was changing fold.c to not look for a fold level
 after a marker, and recompiling. Now everything seems to work great,
 and I don't notice any slowdown.
 
 Perhaps there should be an option for not interpreting numbers after a
 fold marker as a fold level, but I don't know if this is causing
 enough people grief that it would be included. I'm happy with my quick
 fix for now.

 I am surprised that {0} is recognized as a fold marker.  Do you
have 'foldmarker' set to the default value of {{{,}}} or something else?
In my limited tests (try zc in Normal mode and see whether vim throws an
error message) {0} is not recognized as a fold marker but {{{0}}} is.

I have foldmarker set to {,} to make folds automatically in languages
like C, C++, Java, C#, PHP, Perl, etc.

-- 
Be seeing you.



Re: foldmethod=expr very slow

2006-07-26 Thread Peter Hodge
Hi Thore,

You can probably get away with foldmethod=expr in large files by de-activating
it in Insert mode.  I.e., add this to your after/ftplugin/php.vim:

  augroup FastFold
  autocmd!
  autocmd InsertEnter * if ft == 'php' | setlocal foldmethod=manual | endif
  autocmd Insertleave * if ft == 'php' | setlocal foldmethod=expr | endif
  augroup end

I tried it out and it actually seems to work.  Folds are re-evaluated when you
are finished inserting.

HTH,
Peter



--- Thore B. Karlsen [EMAIL PROTECTED] wrote:

 On Mon, 24 Jul 2006 23:48:12 -0500, Thore B. Karlsen [EMAIL PROTECTED]
 wrote:
 
 Hi Thore,
 
 I've never tried folding like this before, and unfortunately I don't have
 time
 to try out this 'optimized' version, but it may work faster for you (I've
 just
 replaced the regex matches with stridx and rearranged the code flow):
 
   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
 
 Thanks! I did a quick test, and that does appear to speed it up. One
 of the files that was giving me problems before is now fast enough to
 work in. There's still a slight latency when I type, but it's much
 better. I'll do some more testing to see how it works in other files,
 but this looks promising!
 
 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.
 
 -- 
 Be seeing you.
 
 


Send instant messages to your online friends http://au.messenger.yahoo.com 


foldmethod=expr very slow

2006-07-24 Thread Thore B . Karlsen

I use foldmethod=expr with the following foldexpr:

set foldexpr=GetFoldLevel(v:lnum) 

function! GetFoldLevel(line) 
   let line_text = getline(a:line) 
   if (line_text =~ '\%({.*}\)\|\%(}.*{\)')
  return '=' 
   elseif (line_text =~ '{') 
  return a1 
   elseif (line_text =~ '}') 
  return s1 
   endif 
   return '=' 
endfunction 

What I want to do is similar to foldmethod=marker with foldmarker={,},
but if I use foldmethod=marker vim gets confused by lines that contain
both { and } like these:

  string s = String.Format({0}, v);
  string[] sa = new string[] { a, b };

GetFoldLevel() above fixes that, in that it keeps the same fold level
if both { and } are found on the same line, but it is horribly slow.
Even in pretty small files (1k lines long), it can take several
seconds for characters to appear when I'm typing in insert mode.

Is there a way to optimize the above, or an alternative way of doing
this? It is very frustrating to have my folds get out of whack with
foldmethod=marker, but the slowness of this foldexpr is unbearable.

-- 
Be seeing you.



Re: foldmethod=expr very slow

2006-07-24 Thread Gautam Iyer
On Mon, Jul 24, 2006 at 12:30:07PM -0500, Thore B. Karlsen wrote:

 I use foldmethod=expr with the following foldexpr:
 
 set foldexpr=GetFoldLevel(v:lnum) 
 
 function! GetFoldLevel(line) 
let line_text = getline(a:line) 
if (line_text =~ '\%({.*}\)\|\%(}.*{\)')
   return '=' 
elseif (line_text =~ '{') 
   return a1 
elseif (line_text =~ '}') 
   return s1 
endif 
return '=' 
 endfunction 
 

I haven't read the above too carefully: But if all you want to do is
fold your code based on {...} blocks, then use Vim 7 and set fdm=syntax
(for C / C++ files).

Incidentally, fdm=syntax is also slow (though much much faster than
fdm=expr). I could (grudgingly) live with a short delay when first
loading the file. The thing that bothers me is that when I switch
between buffers, Vim takes it's own sweet time to get the syntax based
folding right.

So I only enable syntax folding for files that have less than 3000
lines. Once my clever spies steal Benji Fisher's computer, I'm going to
up this limit to 18000.

GI

-- 
You're not drunk if you can lie on the floor without holding on.


Re: foldmethod=expr very slow

2006-07-24 Thread Thore B . Karlsen
On Mon, 24 Jul 2006 13:06:47 -0500, Gautam Iyer
[EMAIL PROTECTED] wrote:

 I use foldmethod=expr with the following foldexpr:
 
 set foldexpr=GetFoldLevel(v:lnum) 
 
 function! GetFoldLevel(line) 
let line_text = getline(a:line) 
if (line_text =~ '\%({.*}\)\|\%(}.*{\)')
   return '=' 
elseif (line_text =~ '{') 
   return a1 
elseif (line_text =~ '}') 
   return s1 
endif 
return '=' 
 endfunction 

I haven't read the above too carefully: But if all you want to do is
fold your code based on {...} blocks, then use Vim 7 and set fdm=syntax
(for C / C++ files).

Unfortunately, that doesn't work for the way I do my folding. I also
insert braces manually in comments where I want folds, e.g.:

  //@{ Private data.

  private int blah;

  //@}

Incidentally, fdm=syntax is also slow (though much much faster than
fdm=expr). I could (grudgingly) live with a short delay when first
loading the file. The thing that bothers me is that when I switch
between buffers, Vim takes it's own sweet time to get the syntax based
folding right.

I wonder why, because you'd think it would be about the same work as
just figuring out the syntax highlighting?

So I only enable syntax folding for files that have less than 3000
lines. Once my clever spies steal Benji Fisher's computer, I'm going to
up this limit to 18000.

I have a quad qore Opteron machine, perhaps if vim could take
advantage of all the CPUs it would be tolerable. :)

-- 
Be seeing you.



Re: foldmethod=expr very slow

2006-07-24 Thread Peter Hodge
Hi Thore,

I've never tried folding like this before, and unfortunately I don't have time
to try out this 'optimized' version, but it may work faster for you (I've just
replaced the regex matches with stridx and rearranged the code flow):

  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


HTH,
Peter



--- Thore B. Karlsen [EMAIL PROTECTED] wrote:


 I use foldmethod=expr with the following foldexpr:

 set foldexpr=GetFoldLevel(v:lnum)

 function! GetFoldLevel(line)
let line_text = getline(a:line)
if (line_text =~ '\%({.*}\)\|\%(}.*{\)')
   return '='
elseif (line_text =~ '{')
   return a1
elseif (line_text =~ '}')
   return s1
endif
return '='
 endfunction

 What I want to do is similar to foldmethod=marker with foldmarker={,},
 but if I use foldmethod=marker vim gets confused by lines that contain
 both { and } like these:

   string s = String.Format({0}, v);
   string[] sa = new string[] { a, b };

 GetFoldLevel() above fixes that, in that it keeps the same fold level
 if both { and } are found on the same line, but it is horribly slow.
 Even in pretty small files (1k lines long), it can take several
 seconds for characters to appear when I'm typing in insert mode.

 Is there a way to optimize the above, or an alternative way of doing
 this? It is very frustrating to have my folds get out of whack with
 foldmethod=marker, but the slowness of this foldexpr is unbearable.

 --
 Be seeing you.




Send instant messages to your online friends http://au.messenger.yahoo.com