Wednesday, December 26, 2012

Re: Fold expression called too often

On Sunday, December 23, 2012 12:09:21 PM UTC-6, Marco wrote:
> On 2012–12–23 Ben Fritz wrote:
>
>
>
> > From :help fold-expr:
>
> >
>
> > > Try to avoid the "=", "a" and "s" return values, since Vim often has to search
>
> > > backwards for a line for which the fold level is defined. This can be slow.
>
> >
>
> > The problem is that Vim calls your foldexpr once for every line,
>
> > but for each line using =, a, or s, it must call it recursively on
>
> > the previous line to get the foldlevel of that line, which calls
>
> > it recursively again to get the previous line for its own
>
> > foldlevel, etc. where the recursion only ends when a foldlevel is
>
> > defined explicitly (at the first line in the file).
>
>
>
> That explains it, thanks.
>
>
>
> > To avoid this you could store foldlevels of previous lines in a
>
> > lookup table internally to your function, and look up the
>
> > foldlevel from your variable if present, or using the foldlevel()
>
> > function instead of returning =, a, and s items.
>
>
>
> I read the manual entry about foldlevel() but I didn't really grasp
>
> the idea (it's my first attempt at writing a fold expression). How
>
> to use foldlevel() to create an efficient expression for a file like
>
> the following?
>


I've not actually done this before, because '=', 'a', and 's' tend to work fine for me in the limited contexts I use them in.

Something like this pseudocode is what I meant (adjust for a:var syntax and to complete the logic, obviously untested):

" recalculating fold levels so discard stored levels
function MyFoldLevel(line)
if line==1
let foldlevels = []
endif
return MyFoldLevelHelper(line)
endfunction

function MyFoldLevelHelper(line)
if foldlevels[line] is not defined
if line==0
return 0
elseif getline(line) contains "start"
let foldlevels[line]=MyFoldLevelHelper(line-1)+1
elseif getline(line) contains "stop"
let foldlevels[line]=MyFoldLevelHelper(line-1)-1
else
let foldlevels[line]=MyFoldLevelHelper(line-1)
endif
endif
return foldlevels[line]
endfunction

It looks like there may be other problems as well in the Vim code, but this approach should allow for greater efficiency regardless.

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

No comments: