From ca2551bc9b6a0c65b6fa83406fcfdc80d465759c Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 17 Dec 2020 21:53:14 -0500 Subject: 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 --- src/nvim/ex_docmd.c | 6 ++--- src/nvim/ex_session.c | 42 ++++++++++++++++++++++++++++----- src/nvim/testdir/test_mksession.vim | 47 +++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 10 deletions(-) (limited to 'src') 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() -- cgit From c60f7c206402c8ab3f2fe5539953d410be2a322c Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 17 Dec 2020 23:21:24 -0500 Subject: vim-patch:8.1.0151: mksession test fails on MS-Windows Problem: Mksession test fails on MS-Windows. Solution: Always use an argument for :lcd. https://github.com/vim/vim/commit/81e2ac7bb68a0321529ad5c89c8674caab4bca6b --- src/nvim/testdir/test_mksession.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim index b5add884f6..d63c8c7f4b 100644 --- a/src/nvim/testdir/test_mksession.vim +++ b/src/nvim/testdir/test_mksession.vim @@ -223,9 +223,9 @@ endfunc func Test_mksession_lcd_multiple_tabs() tabnew tabnew - lcd + lcd . tabfirst - lcd + lcd . mksession! Xtest_mks.out tabonly source Xtest_mks.out -- cgit From f0a8ccff8fce91676b16ccf74971937466468d4c Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 17 Dec 2020 23:29:27 -0500 Subject: vim-patch:8.1.0790: code for creating tabpages in session is too complex Problem: Code for creating tabpages in session is too complex. Solution: Simplify the code. (Jason Franklin) https://github.com/vim/vim/commit/57a6bf056715bd5c94d8047247615e39862424e7 --- src/nvim/ex_session.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index 8d4f1a7cee..14dac9a126 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -613,21 +613,13 @@ static int makeopens(FILE *fd, char_u *dirnow) 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) { + FOR_ALL_TABS(tp) { + if (tp->tp_next != NULL && 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)) { + if (first_tabpage->tp_next != NULL && put_line(fd, "tabrewind") == FAIL) { return FAIL; } } -- cgit From d2837d5efce31c52f9c90344560a7fcc446ccee8 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 17 Dec 2020 01:55:12 -0500 Subject: vim-patch:8.1.2100: :mksession is not sufficiently tested Problem: :mksession is not sufficiently tested. Solution: Add more test cases. (Yegappan Lakshmanan, closes vim/vim#4993) https://github.com/vim/vim/commit/ee1a2b5a2a44dde9b4e9b34141b4d1c7b0e0513f --- src/nvim/testdir/test_mksession.vim | 122 ++++++++++++++++++++++++++++++++++-- 1 file changed, 117 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim index d63c8c7f4b..f71da92bf8 100644 --- a/src/nvim/testdir/test_mksession.vim +++ b/src/nvim/testdir/test_mksession.vim @@ -178,15 +178,20 @@ func Test_mksession_rtp() set sessionoptions& endfunc -" Verify that arglist is stored correctly to the session file. func Test_mksession_arglist() %argdel next file1 file2 file3 file4 + new + next | next mksession! Xtest_mks.out source Xtest_mks.out call assert_equal(['file1', 'file2', 'file3', 'file4'], argv()) + call assert_equal(2, argidx()) + wincmd w + call assert_equal(0, argidx()) call delete('Xtest_mks.out') + enew | only argdel * endfunc @@ -403,24 +408,28 @@ func Test_mksession_globals() set sessionoptions+=globals " create different global variables - let g:Global_string = "Sun is shining" + let g:Global_string = "Sun is shining\r\n" let g:Global_count = 100 let g:Global_pi = 3.14 + let g:Global_neg_float = -2.68 mksession! Xtest_mks.out unlet g:Global_string unlet g:Global_count unlet g:Global_pi + unlet g:Global_neg_float source Xtest_mks.out - call assert_equal("Sun is shining", g:Global_string) + call assert_equal("Sun is shining\r\n", g:Global_string) call assert_equal(100, g:Global_count) call assert_equal(3.14, g:Global_pi) + call assert_equal(-2.68, g:Global_neg_float) unlet g:Global_string unlet g:Global_count unlet g:Global_pi + unlet g:Global_neg_float call delete('Xtest_mks.out') set sessionoptions& endfunc @@ -479,20 +488,123 @@ func Test_mksession_resize() for line in lines if line =~ '^set lines=' let found_resize = v:true + break endif endfor - call assert_equal(v:false, found_resize) + call assert_false(found_resize) let lines = readfile('Xtest_mks2.out') let found_resize = v:false for line in lines if line =~ '^set lines=' let found_resize = v:true + break + endif + endfor + call assert_true(found_resize) + + call delete('Xtest_mks1.out') + call delete('Xtest_mks2.out') + set sessionoptions& +endfunc + +" Test for mksession with a named scratch buffer +func Test_mksession_scratch() + set sessionoptions&vi + enew | only + file Xscratch + set buftype=nofile + mksession! Xtest_mks.out + %bwipe + source Xtest_mks.out + call assert_equal('Xscratch', bufname('')) + call assert_equal('nofile', &buftype) + %bwipe + call delete('Xtest_mks.out') + set sessionoptions& +endfunc + +" Test for mksession with fold options +func Test_mksession_foldopt() + set sessionoptions-=options + set sessionoptions+=folds + new + setlocal foldenable + setlocal foldmethod=expr + setlocal foldmarker=<<<,>>> + setlocal foldignore=% + setlocal foldlevel=2 + setlocal foldminlines=10 + setlocal foldnestmax=15 + mksession! Xtest_mks.out + close + %bwipe + + source Xtest_mks.out + call assert_true(&foldenable) + call assert_equal('expr', &foldmethod) + call assert_equal('<<<,>>>', &foldmarker) + call assert_equal('%', &foldignore) + call assert_equal(2, &foldlevel) + call assert_equal(10, &foldminlines) + call assert_equal(15, &foldnestmax) + + close + %bwipe + set sessionoptions& +endfunc + +" Test for mksession with window position +func Test_mksession_winpos() + if !has('gui_running') + " Only applicable in GUI Vim + return + endif + set sessionoptions+=winpos + mksession! Xtest_mks.out + let found_winpos = v:false + let lines = readfile('Xtest_mks.out') + for line in lines + if line =~ '^winpos ' + let found_winpos = v:true + break + endif + endfor + call assert_true(found_winpos) + call delete('Xtest_mks.out') + set sessionoptions& +endfunc + +" Test for mksession with 'compatible' option +func Test_mksession_compatible() + throw 'skipped: Nvim does not support "compatible" option' + mksession! Xtest_mks1.out + set compatible + mksession! Xtest_mks2.out + set nocp + + let test_success = v:false + let lines = readfile('Xtest_mks1.out') + for line in lines + if line =~ '^if &cp | set nocp | endif' + let test_success = v:true + break + endif + endfor + call assert_true(test_success) + + let test_success = v:false + let lines = readfile('Xtest_mks2.out') + for line in lines + if line =~ '^if !&cp | set cp | endif' + let test_success = v:true + break endif endfor - call assert_equal(v:true, found_resize) + call assert_true(test_success) call delete('Xtest_mks1.out') call delete('Xtest_mks2.out') + set compatible& set sessionoptions& endfunc -- cgit