changeset 14266:7346b2ea80d8 v8.1.0149

patch 8.1.0149: session is wrong with multiple tabs when :lcd was used commit https://github.com/vim/vim/commit/26d4b896a789e65df7ee0cf3e25056eabc523fda Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jul 4 22:26:28 2018 +0200 patch 8.1.0149: session is wrong with multiple tabs when :lcd was used Problem: The generated sessions file does not restore tabs properly if :lcd was used in one of them. Solution: Create the tab pages before setting the directory. (Yee Cheng Chin, closes #3152)
author Christian Brabandt <cb@256bit.org>
date Wed, 04 Jul 2018 22:30:05 +0200
parents 80ca26dbc054
children 8607483b130f
files src/ex_docmd.c src/testdir/test_mksession.vim src/version.c
diffstat 3 files changed, 87 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -5491,7 +5491,7 @@ ex_abclear(exarg_T *eap)
 ex_autocmd(exarg_T *eap)
 {
     /*
-     * Disallow auto commands from .exrc and .vimrc in current
+     * Disallow autocommands from .exrc and .vimrc in current
      * directory for security reasons.
      */
     if (secure)
@@ -11080,10 +11080,13 @@ makeopens(
 #endif
 
     /*
-     * Close all windows but one.
+     * Close all windows and tabs but one.
      */
     if (put_line(fd, "silent only") == FAIL)
 	return FAIL;
+    if ((ssop_flags & SSOP_TABPAGES)
+	    && put_line(fd, "silent tabonly") == FAIL)
+	return FAIL;
 
     /*
      * Now a :cd command to the session directory or the current directory
@@ -11193,9 +11196,33 @@ makeopens(
      */
     tab_firstwin = firstwin;	/* first window in tab page "tabnr" */
     tab_topframe = topframe;
+    if ((ssop_flags & SSOP_TABPAGES))
+    {
+	int	num_tabs;
+
+	/*
+	 * Similar to ses_win_rec() below, populate the tab pages first so
+	 * later local options won't be copied to the new tabs.
+	 */
+	for (tabnr = 1; ; ++tabnr)
+	{
+	    tabpage_T *tp = find_tabpage(tabnr);
+
+	    if (tp == NULL)	/* done all tab pages */
+		break;
+
+	    if (tabnr > 1 && put_line(fd, "tabnew") == FAIL)
+		return FAIL;
+	}
+
+	num_tabs = tabnr - 1;
+	if (num_tabs > 1 && (fprintf(fd, "tabnext -%d", num_tabs - 1) < 0
+						       || put_eol(fd) == FAIL))
+	    return FAIL;
+    }
     for (tabnr = 1; ; ++tabnr)
     {
-	int	need_tabnew = FALSE;
+	int	need_tabnext = FALSE;
 	int	cnr = 1;
 
 	if ((ssop_flags & SSOP_TABPAGES))
@@ -11215,7 +11242,7 @@ makeopens(
 		tab_topframe = tp->tp_topframe;
 	    }
 	    if (tabnr > 1)
-		need_tabnew = TRUE;
+		need_tabnext = TRUE;
 	}
 
 	/*
@@ -11233,11 +11260,14 @@ makeopens(
 #endif
 		    )
 	    {
-		if (fputs(need_tabnew ? "tabedit " : "edit ", fd) < 0
+		if (need_tabnext && put_line(fd, "tabnext") == FAIL)
+		    return FAIL;
+		need_tabnext = FALSE;
+
+		if (fputs("edit ", fd) < 0
 			      || ses_fname(fd, wp->w_buffer, &ssop_flags, TRUE)
 								       == FAIL)
 		    return FAIL;
-		need_tabnew = FALSE;
 		if (!wp->w_arg_idx_invalid)
 		    edited_win = wp;
 		break;
@@ -11245,7 +11275,7 @@ makeopens(
 	}
 
 	/* If no file got edited create an empty tab page. */
-	if (need_tabnew && put_line(fd, "tabnew") == FAIL)
+	if (need_tabnext && put_line(fd, "tabnext") == FAIL)
 	    return FAIL;
 
 	/*
@@ -11348,7 +11378,7 @@ makeopens(
     /*
      * Wipe out an empty unnamed buffer we started in.
      */
-    if (put_line(fd, "if exists('s:wipebuf') && s:wipebuf != bufnr('%')")
+    if (put_line(fd, "if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0")
 								       == FAIL)
 	return FAIL;
     if (put_line(fd, "  silent exe 'bwipe ' . s:wipebuf") == FAIL)
--- a/src/testdir/test_mksession.vim
+++ b/src/testdir/test_mksession.vim
@@ -162,6 +162,53 @@ func Test_mksession_one_buffer_two_windo
   call delete('Xtest_mks.out')
 endfunc
 
+func Test_mksession_lcd_multiple_tabs()
+  tabnew
+  tabnew
+  lcd
+  tabfirst
+  lcd
+  mksession! Xtest_mks.out
+  tabonly
+  source Xtest_mks.out
+  call assert_true(haslocaldir(), 'Tab 1 localdir')
+  tabnext 2
+  call assert_true(!haslocaldir(), 'Tab 2 localdir')
+  tabnext 3
+  call assert_true(haslocaldir(), 'Tab 3 localdir')
+  call delete('Xtest_mks.out')
+endfunc
+
+func Test_mksession_blank_tabs()
+  tabnew
+  tabnew
+  tabnew
+  tabnext 3
+  mksession! Xtest_mks.out
+  tabnew
+  tabnew
+  tabnext 2
+  source Xtest_mks.out
+  call assert_equal(4, tabpagenr('$'), 'session restore should restore number of tabs')
+  call assert_equal(3, tabpagenr(), 'session restore should restore the active tab')
+  call delete('Xtest_mks.out')
+endfunc
+
+func Test_mksession_blank_windows()
+  split
+  split
+  split
+  3 wincmd w
+  mksession! Xtest_mks.out
+  split
+  split
+  2 wincmd w
+  source Xtest_mks.out
+  call assert_equal(4, winnr('$'), 'session restore should restore number of windows')
+  call assert_equal(3, winnr(), 'session restore should restore the active window')
+  call delete('Xtest_mks.out')
+endfunc
+
 if has('terminal')
 
 func Test_mksession_terminal_shell()
--- a/src/version.c
+++ b/src/version.c
@@ -790,6 +790,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    149,
+/**/
     148,
 /**/
     147,