Currently, sourcing a session script that creates multiple tabs will
create multiple empty buffers as an unintended side effect (these buffers
did not exist when the session was written).  This only seems to happen
when 'hidden' is set.

Reproduce:

1. vim --clean +'set hidden'
2. :edit foo | tabedit bar | tabedit baz
3. :tabdo write
3. :mks!
4. :qa!
5. vim --clean +'set hidden' -S
6. :ls

Now you can see that additional buffers were created.  The buffer list also,
surprisingly, starts at 2 instead of 1 (this will be fixed as a side-effect
of this patch).

We can test our fix with:


diff --git a/src/testdir/test_mksession.vim b/src/testdir/test_mksession.vim
index 4d524da0d..db631f395 100644
--- a/src/testdir/test_mksession.vim
+++ b/src/testdir/test_mksession.vim
@@ -198,6 +198,27 @@ func Test_mksession_blank_tabs()
   call delete('Xtest_mks.out')
 endfunc
 
+func Test_mksession_buffer_count()
+  set hidden
+
+  " Edit exactly three files in the current session.
+  %bwipe!
+  e Xfoo | tabe Xbar | tabe Xbaz
+  tabdo write
+  mksession! Xtest_mks.out
+
+  " Verify that loading the session does not create additional buffers.
+  %bwipe!
+  source Xtest_mks.out
+  call assert_equal(3, len(getbufinfo()))
+
+  " Clean up.
+  call delete('Xfoo') | call delete('Xbar') | call delete('Xbaz')
+  call delete('Xtest_mks.out')
+  %bwipe!
+  set hidden&
+endfunc
+
 if has('extra_search')
 
 func Test_mksession_hlsearch()


The patch that I found that will fix the problem is here:


diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 8a9b2f4bf..dd8647ac3 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -11331,26 +11331,6 @@ makeopens(
     if (put_line(fd, "set shortmess=aoO") == FAIL)
        return FAIL;
 
-    /* Now put the other buffers into the buffer list */
-    FOR_ALL_BUFFERS(buf)
-    {
-       if (!(only_save_windows && buf->b_nwindows == 0)
-               && !(buf->b_help && !(ssop_flags & SSOP_HELP))
-#ifdef FEAT_TERMINAL
-               /* skip terminal buffers: finished ones are not useful, others
-                * will be resurrected and result in a new buffer */
-               && !bt_terminal(buf)
-#endif
-               && buf->b_fname != NULL
-               && buf->b_p_bl)
-       {
-           if (fprintf(fd, "badd +%ld ", buf->b_wininfo == NULL ? 1L
-                                          : buf->b_wininfo->wi_fpos.lnum) < 0
-                   || ses_fname(fd, buf, &ssop_flags, TRUE) == FAIL)
-               return FAIL;
-       }
-    }
-
     /* the global argument list */
     if (ses_arglist(fd, "argglobal", &global_alist.al_ga,
                            !(ssop_flags & SSOP_CURDIR), &ssop_flags) == FAIL)
@@ -11578,6 +11558,28 @@ makeopens(
     if (restore_stal && put_line(fd, "set stal=1") == FAIL)
        return FAIL;
 
+    // Add all buffers to the buffer list.  If a buffer was already set to be
+    // added above (with ":edit", for example), the command written here will
+    // have no effect.
+    FOR_ALL_BUFFERS(buf)
+    {
+       if (!(only_save_windows && buf->b_nwindows == 0)
+               && !(buf->b_help && !(ssop_flags & SSOP_HELP))
+#ifdef FEAT_TERMINAL
+               /* skip terminal buffers: finished ones are not useful, others
+                * will be resurrected and result in a new buffer */
+               && !bt_terminal(buf)
+#endif
+               && buf->b_fname != NULL
+               && buf->b_p_bl)
+       {
+           if (fprintf(fd, "badd +%ld ", buf->b_wininfo == NULL ? 1L
+                                          : buf->b_wininfo->wi_fpos.lnum) < 0
+                   || ses_fname(fd, buf, &ssop_flags, TRUE) == FAIL)
+               return FAIL;
+       }
+    }
+
     /*
      * Wipe out an empty unnamed buffer we started in.
      */


This places all of the ":badd" invocations at the bottom of the session.
The effect is that visible buffers are added first (which means they replace
the empty buffers in the windows they occupy). Adding all of the buffers
at the end then adds buffers that do not occupy a window.  Running :badd on
a buffer that is already in the list has no effect, so it doesn't hurt to
leave it.

I hope I didn't miss anything here.  I think my reasoning is sound.

Best wishes,
Jason Franklin

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

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui