aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2020-12-17 21:53:14 -0500
committerJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2020-12-29 22:31:20 -0500
commitca2551bc9b6a0c65b6fa83406fcfdc80d465759c (patch)
treeda34b9daca3146aa1f7394b5dbee64099e3fd3cf
parentc762f5220b02036e4eb9097a1d2a9fded6375fa0 (diff)
downloadrneovim-ca2551bc9b6a0c65b6fa83406fcfdc80d465759c.tar.gz
rneovim-ca2551bc9b6a0c65b6fa83406fcfdc80d465759c.tar.bz2
rneovim-ca2551bc9b6a0c65b6fa83406fcfdc80d465759c.zip
vim-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 vim/vim#3152) https://github.com/vim/vim/commit/26d4b896a789e65df7ee0cf3e25056eabc523fda
-rw-r--r--src/nvim/ex_docmd.c6
-rw-r--r--src/nvim/ex_session.c42
-rw-r--r--src/nvim/testdir/test_mksession.vim47
3 files changed, 85 insertions, 10 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 3fc02e0693..35b0755bd8 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -4769,10 +4769,8 @@ static void ex_abclear(exarg_T *eap)
static void ex_autocmd(exarg_T *eap)
{
- /*
- * Disallow auto commands from .exrc and .vimrc in current
- * directory for security reasons.
- */
+ // Disallow autocommands from .exrc and .vimrc in current
+ // directory for security reasons.
if (secure) {
secure = 2;
eap->errmsg = e_curdir;
diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c
index d831ffc050..8d4f1a7cee 100644
--- a/src/nvim/ex_session.c
+++ b/src/nvim/ex_session.c
@@ -526,8 +526,12 @@ static int makeopens(FILE *fd, char_u *dirnow)
}
}
- // Close all windows but one.
+ // Close all windows and tabs but one.
PUTLINE_FAIL("silent only");
+ 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
@@ -606,13 +610,34 @@ static int makeopens(FILE *fd, char_u *dirnow)
//
tab_firstwin = firstwin; // First window in tab page "tabnr".
tab_topframe = topframe;
+ if ((ssop_flags & SSOP_TABPAGES)) {
+ // 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++) {
+ const tabpage_T *const tp = find_tabpage(tabnr);
+
+ if (tp == NULL) { // done all tab pages
+ break;
+ }
+ if (tabnr > 1 && put_line(fd, "tabnew") == FAIL) {
+ return FAIL;
+ }
+ }
+
+ const int 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++) {
tabpage_T *tp = find_tabpage(tabnr);
if (tp == NULL) {
break; // done all tab pages
}
- int need_tabnew = false;
+ bool need_tabnext = false;
int cnr = 1;
if ((ssop_flags & SSOP_TABPAGES)) {
@@ -624,7 +649,7 @@ static int makeopens(FILE *fd, char_u *dirnow)
tab_topframe = tp->tp_topframe;
}
if (tabnr > 1) {
- need_tabnew = true;
+ need_tabnext = true;
}
}
@@ -639,11 +664,15 @@ static int makeopens(FILE *fd, char_u *dirnow)
&& !bt_help(wp->w_buffer)
&& !bt_nofile(wp->w_buffer)
) {
- 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;
}
@@ -652,7 +681,7 @@ static int makeopens(FILE *fd, char_u *dirnow)
}
// 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;
}
@@ -775,6 +804,7 @@ static int makeopens(FILE *fd, char_u *dirnow)
//
if (fprintf(fd, "%s",
"if exists('s:wipebuf') "
+ "&& len(win_findbuf(s:wipebuf)) == 0"
"&& getbufvar(s:wipebuf, '&buftype') isnot# 'terminal'\n"
" silent exe 'bwipe ' . s:wipebuf\n"
"endif\n"
diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim
index 8ef8bbc23a..b5add884f6 100644
--- a/src/nvim/testdir/test_mksession.vim
+++ b/src/nvim/testdir/test_mksession.vim
@@ -220,6 +220,53 @@ func Test_mksession_one_buffer_two_windows()
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('extra_search')
func Test_mksession_hlsearch()