diff --git a/src/globals.h b/src/globals.h
--- a/src/globals.h
+++ b/src/globals.h
@@ -1168,6 +1168,9 @@
EXTERN int fill_fold INIT(= '-');
EXTERN int fill_diff INIT(= '-');
#endif
+#if defined(FEAT_FOLDING)
+EXTERN int no_fold_update INIT(= FALSE);
+#endif
#ifdef FEAT_VISUAL
/* Whether 'keymodel' contains "stopsel" and "startsel". */
diff --git a/src/misc1.c b/src/misc1.c
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -3032,31 +3032,34 @@
/* Check if a change in the buffer has invalidated the cached
* values for the cursor. */
#ifdef FEAT_FOLDING
- /*
- * Update the folds for this window. Can't postpone this, because
- * a following operator might work on the whole fold: ">>dd".
- */
- foldUpdate(wp, lnum, lnume + xtra - 1);
-
- /* The change may cause lines above or below the change to become
- * included in a fold. Set lnum/lnume to the first/last line that
- * might be displayed differently.
- * Set w_cline_folded here as an efficient way to update it when
- * inserting lines just above a closed fold. */
- i = hasFoldingWin(wp, lnum, &lnum, NULL, FALSE, NULL);
- if (wp->w_cursor.lnum == lnum)
- wp->w_cline_folded = i;
- i = hasFoldingWin(wp, lnume, NULL, &lnume, FALSE, NULL);
- if (wp->w_cursor.lnum == lnume)
- wp->w_cline_folded = i;
-
- /* If the changed line is in a range of previously folded lines,
- * compare with the first line in that range. */
- if (wp->w_cursor.lnum <= lnum)
- {
- i = find_wl_entry(wp, lnum);
- if (i >= 0 && wp->w_cursor.lnum > wp->w_lines[i].wl_lnum)
- changed_line_abv_curs_win(wp);
+ if (!no_fold_update)
+ {
+ /*
+ * Update the folds for this window. Can't postpone this, because
+ * a following operator might work on the whole fold: ">>dd".
+ */
+ foldUpdate(wp, lnum, lnume + xtra - 1);
+
+ /* The change may cause lines above or below the change to become
+ * included in a fold. Set lnum/lnume to the first/last line that
+ * might be displayed differently.
+ * Set w_cline_folded here as an efficient way to update it when
+ * inserting lines just above a closed fold. */
+ i = hasFoldingWin(wp, lnum, &lnum, NULL, FALSE, NULL);
+ if (wp->w_cursor.lnum == lnum)
+ wp->w_cline_folded = i;
+ i = hasFoldingWin(wp, lnume, NULL, &lnume, FALSE, NULL);
+ if (wp->w_cursor.lnum == lnume)
+ wp->w_cline_folded = i;
+
+ /* If the changed line is in a range of previously folded lines,
+ * compare with the first line in that range. */
+ if (wp->w_cursor.lnum <= lnum)
+ {
+ i = find_wl_entry(wp, lnum);
+ if (i >= 0 && wp->w_cursor.lnum > wp->w_lines[i].wl_lnum)
+ changed_line_abv_curs_win(wp);
+ }
}
#endif
diff --git a/src/ops.c b/src/ops.c
--- a/src/ops.c
+++ b/src/ops.c
@@ -4751,6 +4751,10 @@
/* length of a line to force formatting: 3 * 'tw' */
max_len = comp_textwidth(TRUE) * 3;
+#ifdef FEAT_FOLDING
+ no_fold_update++; /* defer fold updates */
+#endif
+
/* check for 'q', '2' and '1' in 'formatoptions' */
#ifdef FEAT_COMMENTS
do_comments = has_format_option(FO_Q_COMS);
@@ -4971,6 +4975,11 @@
}
line_breakcheck();
}
+ /* force update of folds */
+#ifdef FEAT_FOLDING
+ no_fold_update--;
+#endif
+ changed_lines(curwin->w_cursor.lnum, 0, line_count+1, 0L);
}
/*
Hi
On So, 23 Dez 2012, Marco wrote:
> I tried to create a custom fold expression for a file type. The
> folding works as desired, but it makes vim terribly slow. Commands
> like "gwip" to format the current paragraph take more than ten
> seconds on a modern machine. Thanks to Drew [1] I heard about the
> possibility to profile my expression and was surprised that it was
> called millions of times for a file containing just a few dozen
> lines.
>
> I created a simple test expression and it is also called way more
> often than I would expect. Here my test case:
>
> " file: test
> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
> tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At
> vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,
> no sea takimata sanctus est Lorem ipsum dolor sit amet.
> " endfile
>
> " file: myfold.vim
> function! MyFolds()
> let thisline = getline(v:lnum)
>
> if match(thisline, 'start') >= 0
> return "a1"
> elseif match(thisline, 'stop') >= 0
> return "s1"
> else
> return "="
> endfunction
>
> setlocal foldmethod=expr
> setlocal foldexpr=MyFolds()
>
> function! TextManip()
> normal gwip
> endfunction
>
> call TextManip()
> " endfile
>
> This is how I did the profiling:
>
> vim --cmd 'profile start profile.result' \
> --cmd 'profile! file myfold.vim' \
> -c 'source myfold.vim' \
> -c 'profdel file myfold.vim' \
> test
>
> The resulting file profile.result shows that the function MyFolds()
> was called 52 times:
>
> FUNCTIONS SORTED ON TOTAL TIME
> count total (s) self (s) function
> 1 0.000961 0.000252 TextManip()
> 52 0.000709 MyFolds()
>
> The test file contains just four lines. Why is it called 52 times?
> And what can I do about that?
Bram,
foldupdate will be called several times, when formating a paragraph,
because it can be called in del_bytes() function and also in do_join()
function. I wonder, if we can defer the foldupdate until after
formatting has taken place, e.g. something like this patch, which seems
to work so far, but the foldexpression is called not so often.
regards,
Christian
--
Wie man sein Kind nicht nennen sollte:
Sepp Soh
--
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
Monday, December 24, 2012
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment