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.

Attached are a test case and a patch.

To run the test case:
   * vim -u NONE foo.py
   * run:
       :source test.vim
       :mkview
       :loadview
   * the bug shows up after 'loadview': the second fold becomes
     unexpectedly closed

After the test, the view file contains the following lines:
   2
   normal zo
   3
   normal zc
   7
   normal zo
   2
   normal zo

Note that at line 3, 'zc' will close the parent fold and not the first
nested fold since this one is already closed, so that the following
'zo' at line 7 instead of opening the second nested fold, does reopen
again the parent fold.

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

--
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
@@ -3293,6 +3293,7 @@
 #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_fold_open_close __ARGS((FILE *fd, fold_T *fp, linenr_T off));
 
 /*
  * Write commands to "fd" to restore the manual folds in window "wp".
@@ -3367,7 +3368,7 @@
 	{
 	    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)
@@ -3375,19 +3376,47 @@
 		if (put_foldopen_recurse(fd, &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;
+	    /* open the leaf when needed but do not close the leaf, as it is
+	     * already closed and closing it may close its parent */
+	    else if (fp->fd_flags != FD_CLOSED)
+	    {
+		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 */
class C:
    def foo(self):
        pass
        pass

    def bar(self):
        pass
        pass

if __name__ == "__main__":
    main()

Attachment: test.vim
Description: Binary data

Raspunde prin e-mail lui