Loading ...
Sorry, an error occurred while loading the content.

Re: foldmethod=expr and ins-completion

Expand Messages
  • Bram Moolenaar
    ... The problem was identified as the foldexpr returning a fold level relative to the previous line. Vim then had to start at the top of the file to
    Message 1 of 7 , Feb 1, 2001
    • 0 Attachment
      Johannes Zellner wrote:

      > it turns out that it it not really a problem of ins-completion but
      > of typing especially when at the bottom of larger files. As an example
      > try the attached folding vim.vim with a lengthy vim script, e.g. the
      > vim.vim syntax file.
      > # vim -u NONE $VIMRUNTIME/syntax/vim.vim
      > :source vim.vim " <-- this time the attached folding script (not the syntax file)
      > Then go to the BOTTOM of the syntax file, open a line (vim will
      > complain, because $VIMRUNTIME/syntax/vim.vim is not writable)
      > and just type away. It's not usable on my 300 MHz PII.

      The problem was identified as the 'foldexpr' returning a fold level relative
      to the previous line. Vim then had to start at the top of the file to
      recompute all the foldlevels, since it doesn't know which ones had become
      invalid after a change.

      It's possible that folds above a change become invalid, I did not see a way to
      make a generic solution that guesses the foldlevel above the changed text.
      On the other hand, the 'foldexpr' doesn't know which lines have changed.

      I found another solution: The 'foldexpr' can call the foldlevel() function to
      check the existing fold level. Since some of these folds are invalid, it will
      return -1 for these. The 'foldexpr' can use this information to try to
      compute the absolute foldlevel. Vim then doesn't need to go back further.

      The example from Johannes can be updated like this:

      [... computes "delta" as the difference in foldlevel compared to the
      previous line]
      > if delta > 0
      > exe 'return "a'.delta.'"'
      > elseif delta < 0
      > exe 'return "s'.-delta.'"'
      > else
      > return '='
      > endif

      The speed can be improved from "not usable" to "fast" by using these lines

      let lvl = foldlevel(v:lnum - 1)
      if lvl >= 0
      return lvl + delta

      Thus when the foldlevel of the line above the one we are computing the
      foldlevel for is known, it returns an absolute number. Then Vim knows it
      doesn't have to go further back.

      Note that this 'foldexpr' doesn't work correctly for these lines:

      if x

      There is no new fold at "if", because the level doesn't change. ">" should be
      returned here.

      To be rich is not the end, but only a change of worries.

      /// Bram Moolenaar -- Bram@... -- http://www.moolenaar.net \\\
      ((( Creator of Vim - http://www.vim.org -- ftp://ftp.vim.org/pub/vim )))
      \\\ Help me helping AIDS orphans in Uganda - http://iccf-holland.org ///
    Your message has been successfully submitted and would be delivered to recipients shortly.