On Fri, Nov 25, 2011 at 6:48 PM, Xavier de Gaye wrote:
>> I use loadview and mkview with autocommands. It happens quite often
>> that upon returning to a buffer, a fold becomes unexpectedly closed.
>> In that case, whatever fold I attempt to open in this buffer next, it
>> will be closed after I leave the buffer and on returning to it again.
>> ...
>> The patch fixes the problem by never closing a leaf fold (since they
>> are already closed) and not reopening a parent fold after its leaves
>> have been taken care of, when it is an open fold (since it is already
>> open, reopening the parent fold was unfortunately hiding the bug).
>
>
> The patch is not correct.
>
> For a given folding state in a window, when you start building the
> folds after an initial 'zM', then the folds are correct (with the
> above patch).
> For the same  given folding state, when you start building the folds
> after an initial 'zR', then some folds are incorrectly open.


The attached patch fixes this by taking into account the foldlevel to
know when to open or close a fold that is a leaf, in the vim script
written by mkview.


-- 
Xavier

Les Chemins de Lokoti: http://lokoti.alwaysdata.net

-- 
You received this message from the "vim_dev" 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
diff --git a/src/fold.c b/src/fold.c
--- a/src/fold.c
+++ b/src/fold.c
@@ -3292,7 +3292,8 @@
 /* put_folds() {{{2 */
 #if defined(FEAT_SESSION) || defined(PROTO)
 static int put_folds_recurse __ARGS((FILE *fd, garray_T *gap, linenr_T off));
-static int put_foldopen_recurse __ARGS((FILE *fd, garray_T *gap, linenr_T off));
+static int put_foldopen_recurse __ARGS((FILE *fd, win_T *wp, garray_T *gap, linenr_T off));
+static int put_fold_open_close __ARGS((FILE *fd, fold_T *fp, linenr_T off));
 
 /*
  * Write commands to "fd" to restore the manual folds in window "wp".
@@ -3312,7 +3313,7 @@
 
     /* If some folds are manually opened/closed, need to restore that. */
     if (wp->w_fold_manual)
-	return put_foldopen_recurse(fd, &wp->w_folds, (linenr_T)0);
+        return put_foldopen_recurse(fd, wp, &wp->w_folds, (linenr_T)0);
 
     return OK;
 }
@@ -3352,12 +3353,14 @@
  * Returns FAIL when writing failed.
  */
     static int
-put_foldopen_recurse(fd, gap, off)
+put_foldopen_recurse(fd, wp, gap, off)
     FILE	*fd;
+    win_T	*wp;
     garray_T	*gap;
     linenr_T	off;
 {
     int		i;
+    int		level;
     fold_T	*fp;
 
     fp = (fold_T *)gap->ga_data;
@@ -3367,27 +3370,59 @@
 	{
 	    if (fp->fd_nested.ga_len > 0)
 	    {
-		/* open/close nested folds while this fold is open */
+		/* open nested folds while this fold is open */
 		if (fprintf(fd, "%ld", fp->fd_top + off) < 0
 			|| put_eol(fd) == FAIL
 			|| put_line(fd, "normal zo") == FAIL)
 		    return FAIL;
-		if (put_foldopen_recurse(fd, &fp->fd_nested, off + fp->fd_top)
+                if (put_foldopen_recurse(fd, wp, &fp->fd_nested, off + fp->fd_top)
 			== FAIL)
 		    return FAIL;
+		/* close the parent when needed */
+		if (fp->fd_flags == FD_CLOSED)
+		{
+		    if (put_fold_open_close(fd, fp, off) == FAIL)
+			return FAIL;
+		}
 	    }
-	    if (fprintf(fd, "%ld", fp->fd_top + off) < 0
-		    || put_eol(fd) == FAIL
-		    || fprintf(fd, "normal z%c",
-				    fp->fd_flags == FD_CLOSED ? 'c' : 'o') < 0
-		    || put_eol(fd) == FAIL)
-		return FAIL;
+	    else
+	    {
+                /* Open or close the leaf according to the window foldlevel.
+                 * Do not close a leaf that is already closed, as it will close
+                 * the parent. */
+                level = foldLevelWin(wp, off + fp->fd_top);
+                if ((fp->fd_flags == FD_CLOSED && wp->w_p_fdl >= level)
+                    || (fp->fd_flags != FD_CLOSED && wp->w_p_fdl < level))
+		if (put_fold_open_close(fd, fp, off) == FAIL)
+		    return FAIL;
+	    }
 	}
 	++fp;
     }
 
     return OK;
 }
+
+/* put_fold_open_close() {{{2 */
+/*
+ * Write the open or close command to "fd".
+ * Returns FAIL when writing failed.
+ */
+    static int
+put_fold_open_close(fd, fp, off)
+    FILE	*fd;
+    fold_T	*fp;
+    linenr_T	off;
+{
+    if (fprintf(fd, "%ld", fp->fd_top + off) < 0
+	    || put_eol(fd) == FAIL
+	    || fprintf(fd, "normal z%c",
+			   fp->fd_flags == FD_CLOSED ? 'c' : 'o') < 0
+	    || put_eol(fd) == FAIL)
+	return FAIL;
+
+    return OK;
+}
 #endif /* FEAT_SESSION */
 
 /* }}}1 */

Raspunde prin e-mail lui