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

foldmethod=expr and ins-completion

Expand Messages
  • Johannes Zellner
    Hi, ins-completion gets really really slow when foldmethod=expr! I think: 1) no folds should be created while in insert mode. 2) folds that are created after
    Message 1 of 7 , Jan 29, 2001
    • 0 Attachment
      Hi,

      ins-completion gets really really slow when foldmethod=expr!

      I think:
      1) no folds should be created while in insert mode.
      2) folds that are created after the initial creation
      should be created always open.

      --
      Johannes
    • Bram Moolenaar
      ... At what moment? When going through the matches or when accepting a match? ... That s very difficult. The principle is that folds are updated when making
      Message 2 of 7 , Jan 30, 2001
      • 0 Attachment
        Johannes Zellner wrote:

        > ins-completion gets really really slow when foldmethod=expr!

        At what moment? When going through the matches or when accepting a match?

        > I think:
        > 1) no folds should be created while in insert mode.

        That's very difficult. The principle is that folds are updated when making a
        change. Since you could type <Up> any moment, every character you type is a
        change. Postponing updating the folds would require remembering what text
        changed and updating it later.

        > 2) folds that are created after the initial creation
        > should be created always open.

        What is "initial creation"?

        Anyway, I have done quite a bit of work on folding recently. When in Insert
        mode, the whole fold the cursor is in is now open, not just the line where the
        cursor is. And more folds are created open. You'll have to try out the next
        version to check if it works OK now.

        --
        hundred-and-one symptoms of being an internet addict:
        81. At social functions you introduce your husband as "my domain server."

        /// 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 ///
      • Johannes Zellner
        ... while SEARCHING for the matches! If I ve a very short file and set complete=. and there s just one match (so things are really fast), it tells me about 3
        Message 3 of 7 , Jan 30, 2001
        • 0 Attachment
          On Tue, Jan 30, 2001 at 12:48:11PM +0100, Bram Moolenaar wrote:
          >
          > Johannes Zellner wrote:
          >
          > > ins-completion gets really really slow when foldmethod=expr!
          >
          > At what moment? When going through the matches or when accepting a match?

          while SEARCHING for the matches! If I've a very short file and set
          'complete=.' and there's just one match (so things are really fast),
          it tells me about 3 seconds `searching ...'. I turned on verbose=20
          and get pages of output which show that the foldexpr script is executed.

          > > I think:
          > > 1) no folds should be created while in insert mode.
          >
          > That's very difficult. The principle is that folds are updated when making a
          > change. Since you could type <Up> any moment, every character you type is a
          > change. Postponing updating the folds would require remembering what text
          > changed and updating it later.

          I see. what about calling foldexpr (in insert mode) only if the line
          number changed (e.g. on <cr> or <up> ...) ?

          >
          > > 2) folds that are created after the initial creation
          > > should be created always open.
          >
          > What is "initial creation"?

          if displaying a buffer in a new `view' (just opened the first or
          another window for a buffer) folds have to be created for the whole
          buffer obviously.

          > Anyway, I have done quite a bit of work on folding recently. When in Insert
          > mode, the whole fold the cursor is in is now open, not just the line where the
          > cursor is. And more folds are created open. You'll have to try out the next
          > version to check if it works OK now.

          ok.

          --
          Johannes
        • Bram Moolenaar
          ... Very strange. I did a quick test but didn t see the problem. Could you try to find out how the completion code calls the fold-expression? Otherwise, a
          Message 4 of 7 , Jan 30, 2001
          • 0 Attachment
            Johannes Zellner wrote:

            > > > ins-completion gets really really slow when foldmethod=expr!
            > >
            > > At what moment? When going through the matches or when accepting a match?
            >
            > while SEARCHING for the matches! If I've a very short file and set
            > 'complete=.' and there's just one match (so things are really fast),
            > it tells me about 3 seconds `searching ...'. I turned on verbose=20
            > and get pages of output which show that the foldexpr script is executed.

            Very strange. I did a quick test but didn't see the problem. Could you try
            to find out how the completion code calls the fold-expression? Otherwise, a
            short example that reproduces it?

            > > > I think:
            > > > 1) no folds should be created while in insert mode.
            > >
            > > That's very difficult. The principle is that folds are updated when making a
            > > change. Since you could type <Up> any moment, every character you type is a
            > > change. Postponing updating the folds would require remembering what text
            > > changed and updating it later.
            >
            > I see. what about calling foldexpr (in insert mode) only if the line
            > number changed (e.g. on <cr> or <up> ...) ?

            And when you hit <BS> to delete a line-break, or formatting breaks the text,
            or... This quickly gets complicated. It messes up the way it all works too.

            Perhaps your problem is just a bug, let's look into that first.

            > > > 2) folds that are created after the initial creation
            > > > should be created always open.
            > >
            > > What is "initial creation"?
            >
            > if displaying a buffer in a new `view' (just opened the first or
            > another window for a buffer) folds have to be created for the whole
            > buffer obviously.

            I understand. No, when you do "dd" on a sequence of folds and then "p"ut
            them somewhere else I think they should be closed (according to 'foldlevel').
            Only changes around the cursor should create open folds, because that's where
            you want to see the text.

            --
            hundred-and-one symptoms of being an internet addict:
            91. It's Saturday afternoon in the middle of may and you are on computer.

            /// 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 ///
          • Johannes Zellner
            ... 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
            Message 5 of 7 , Jan 30, 2001
            • 0 Attachment
              On Tue, Jan 30, 2001 at 04:55:22PM +0100, Bram Moolenaar wrote:
              >
              > Johannes Zellner wrote:
              >
              > > > > ins-completion gets really really slow when foldmethod=expr!
              > > >
              > > > At what moment? When going through the matches or when accepting a match?
              > >
              > > while SEARCHING for the matches! If I've a very short file and set
              > > 'complete=.' and there's just one match (so things are really fast),
              > > it tells me about 3 seconds `searching ...'. I turned on verbose=20
              > > and get pages of output which show that the foldexpr script is executed.
              >
              > Very strange. I did a quick test but didn't see the problem. Could you try
              > to find out how the completion code calls the fold-expression? Otherwise, a
              > short example that reproduces it?

              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.

              --
              Johannes
            • Bram Moolenaar
              ... [...] ... OK, I can reproduce it now. ... The problem is that your foldexpr returns = , a or s for all lines. This means the fold level is relative
              Message 6 of 7 , Jan 31, 2001
              • 0 Attachment
                Johannes Zellner wrote:

                > > > > > ins-completion gets really really slow when foldmethod=expr!
                [...]
                > 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.

                OK, I can reproduce it now.

                > if delta > 0
                > exe 'return "a'.delta.'"'
                > elseif delta < 0
                > exe 'return "s'.-delta.'"'
                > else
                > return '='
                > endif

                The problem is that your 'foldexpr' returns "=", "a" or "s" for all
                lines. This means the fold level is relative to the level in a previous
                line. When a character has been typed, Vim needs to update the folds.
                To do this, it has to find a line above the typed text for which the
                fold level is defined. Unfortunately, your 'foldexpr' returns a
                relative level for every line, so that it stops only at the first line
                of the file, where the foldlevel is zero. Then from that point all
                folds are checked until the end of the change.

                In this specific case the line above the changed text keeps the old
                foldlevel. We should somehow be able to use this to avoid going back
                further. But in other cases a change in one line could cause a fold
                above it to change, thus the 'foldexpr' must take care of this, since it
                knows where the folds are going to be.

                We could use the foldlevel() function, but there is a catch: Using
                foldlevel() will first update the folds, which is what we were already
                doing! I could implement something that, while updating the folds,
                foldlevel() returns the old level. But it's tricky.

                Another solution would be to require that when using the "expr" fold
                method, the fold level must not change for different text below the
                current line. Then the current level can be re-used, without making
                'foldexpr' more complicated. This will cause something that uses a
                multi-line regexp to stop working. For example, something that
                recognizes the start of a C function.

                This is a function declaration:

                func(
                int a,
                int b,
                );

                This is a function definition:

                func(
                int a,
                int b,
                )
                {

                If you want a fold to start at the "func(", a change in the line with
                the ")" will cause a fold to be created/removed four lines up.

                We probably need some way for the 'foldexpr' to tell Vim how the syncing
                is to be done...

                --
                From "know your smileys":
                8-O "Omigod!!" (done "rm -rf *" ?)

                /// 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 ///
              • 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 7 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
                  first:

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

                  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:

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