Wednesday, March 31, 2010

Re: Why is there no :foldupdate?

set viminfo=
exe "norm! /fold\<cr>"
set foldlevel=0 foldmethod=expr foldexpr=getline(v:lnum)!~getreg('/',1) hls
redraw!
echo "search: fold"
sleep 5
exe "norm! /TRUE\<cr>"
norm! zX
norm! zx
norm! zC
redraw!
echo "search: TRUE"
"foldupdate
diff --git a/runtime/doc/fold.txt b/runtime/doc/fold.txt
index 60704c5..46a62a0 100644
--- a/runtime/doc/fold.txt
+++ b/runtime/doc/fold.txt
@@ -344,6 +344,12 @@ za When on a closed fold: open it. When folds are nested, you
zA When on a closed fold: open it recursively.
When on an open fold: close it recursively and set
'foldenable'.
+ *zU*
+zU Update folds and re-apply 'foldlevel'.
+ (This is usefull, to reevaluate a fold-expression).
+
+:foldu[pdate] *:foldupdate*
+ Force updating folds. Works like "zU".

*zv*
zv View cursor line: Open just enough folds to make the line in
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index bf66b40..319028c 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -399,6 +399,8 @@ EX(CMD_folddoclosed, "folddoclosed", ex_folddo,
RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM),
EX(CMD_foldopen, "foldopen", ex_foldopen,
RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_foldupdate, "foldupdate", ex_foldupdate,
+ TRLBAR),
EX(CMD_for, "for", ex_while,
EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
EX(CMD_function, "function", ex_function,
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index f8795fa..1279451 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -423,10 +423,12 @@ static void ex_X __ARGS((exarg_T *eap));
static void ex_fold __ARGS((exarg_T *eap));
static void ex_foldopen __ARGS((exarg_T *eap));
static void ex_folddo __ARGS((exarg_T *eap));
+static void ex_foldupdate __ARGS(());
#else
# define ex_fold ex_ni
# define ex_foldopen ex_ni
# define ex_folddo ex_ni
+# define ex_foldupdate ex_ni
#endif
#if !((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE)))
@@ -11104,6 +11106,13 @@ ex_X(eap)

#ifdef FEAT_FOLDING
static void
+ex_foldupdate()
+{
+ curwin->w_foldinvalid = TRUE;
+ newFoldLevel();
+}
+
+ static void
ex_fold(eap)
exarg_T *eap;
{
diff --git a/src/normal.c b/src/normal.c
index 8b9fea7..6acfe5b 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -4930,6 +4930,12 @@ dozet:
curwin->w_p_fen = TRUE;
break;

+ /* "zU": Update Folding, replay 'foldlevel' */
+ case 'U': curwin->w_p_fen = TRUE;
+ curwin->w_foldinvalid = TRUE;
+ old_fdl = -1; /* force an update */
+ break;
+
/* "zv": open folds at the cursor */
case 'v': foldOpenCursor();
break;
(fullquote, because copying vim_dev)

On Mi, 31 Mär 2010, Christian Brabandt wrote:

> Hi,
>
> sometimes I am using fold expressions to simply hide away unwanted
> parts. Usually this boils down to
> :set fdm=expr fde=getline(v:lnum)!~getreg('/',1)
>
> While this works fine, it is only limited to whatever was in register @/
> when this setting was entered. Now this leaves an interesting question:
> When are 'foldexpr' reevaluated (are they at all)? Reading :h fold.txt
> does not mentioned when the fold expressions are reevaluated and folds
> are updated (or I might have missed it).
>
> Now the obvious cure to this is to reenter the foldexpression. So if I
> am searching for a different term, I need to enter
> :set fde=getline(v:lnum)!~getreg('/',1)
> and the folds will be updated.
>
> Of course, I could define my own :Foldupdate like this:
> :com! Foldupdate :exe "set fde=".&fde
>
> But this looks so fundamental, that I am wondering, whether I am the
> only one who is missing :foldupdate. Does anybody else think so? Or am I
> missing something obvious?
>
> PS: Looking at the source, it does not seem too hard, to define an extra
> :foldupdate command. Does that sound like a reasonable idea? I could
> prepare a patch for this, if there is interest.
>
> regards,
> Christian
>
> (Actually, I'd really like an RegisterChanged autocommand event, which
> could trigger an :foldupdate)

Ok, here is a patch, that implements :foldupdate as ex command and zU as
normal mode command.

Here is the testcase:
go to the vim-Src directory and execute the attached vim-script:

chrisbra t41:~/vim/src [1296]% ./vim -u NONE -N -S foldupdate.vim eval.c

Note, how the folding will be wrong, after the second search command
(and I have found no way to refresh the folding. zx and zX do not work,
though its description led me believe it could have. Well actually I
found one way: filtering the whole buffer through cat will also update
the folding)

When recompiling vim with the patch, the folding will be updated, when
:foldupdate is called.

regards,
Christian

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

To unsubscribe, reply using "remove me" as the subject.

No comments: