diff options
author | Evgeni Chasnovski <evgeni.chasnovski@gmail.com> | 2022-01-14 13:19:43 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-01-14 13:19:43 +0000 |
commit | 26ebf1f036517ebeacf571c333a83cca7e13bbe2 (patch) | |
tree | 8c5320fa47ada542a540d0fadbae201ccf2fbd41 /src | |
parent | 7bfa6d698e7a9f586251d53cd092ad6e8110e045 (diff) | |
download | vim-git-26ebf1f036517ebeacf571c333a83cca7e13bbe2.tar.gz |
patch 8.2.4090: after restoring a session buffer order can be quite differentv8.2.4090
Problem: After restoring a session buffer order can be quite different.
Solution: Create buffers first. (Evgeni Chasnovski, closes #9520)
Diffstat (limited to 'src')
-rw-r--r-- | src/session.c | 51 | ||||
-rw-r--r-- | src/testdir/test_mksession.vim | 25 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 54 insertions, 24 deletions
diff --git a/src/session.c b/src/session.c index 21af90245..68e40db80 100644 --- a/src/session.c +++ b/src/session.c @@ -690,6 +690,28 @@ makeopens( if (put_line(fd, "set shortmess=aoO") == FAIL) goto fail; + // Put all buffers into the buffer list. + // Do it very early to preserve buffer order after loading session (which + // can be disrupted by prior `edit` or `tabedit` calls). + 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) + goto fail; + } + } + // the global argument list if (ses_arglist(fd, "argglobal", &global_alist.al_ga, !(ssop_flags & SSOP_CURDIR), &ssop_flags) == FAIL) @@ -741,7 +763,11 @@ makeopens( // Similar to ses_win_rec() below, populate the tab pages first so // later local options won't be copied to the new tabs. FOR_ALL_TABPAGES(tp) - if (tp->tp_next != NULL && put_line(fd, "tabnew") == FAIL) + // Use `bufhidden=wipe` to remove empty "placeholder" buffers once + // they are not needed. This prevents creating extra buffers (see + // cause of patch 8.1.0829) + if (tp->tp_next != NULL + && put_line(fd, "tabnew +setlocal\\ bufhidden=wipe") == FAIL) goto fail; if (first_tabpage->tp_next != NULL && put_line(fd, "tabrewind") == FAIL) goto fail; @@ -919,29 +945,6 @@ makeopens( if (restore_stal && put_line(fd, "set stal=1") == FAIL) goto fail; - // Now put the remaining buffers into the buffer list. - // This is near the end, so that when 'hidden' is set we don't create extra - // buffers. If the buffer was already created with another command the - // ":badd" 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) - goto fail; - } - } - // Wipe out an empty unnamed buffer we started in. if (put_line(fd, "if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0") == FAIL) diff --git a/src/testdir/test_mksession.vim b/src/testdir/test_mksession.vim index 301ff0514..494ac873b 100644 --- a/src/testdir/test_mksession.vim +++ b/src/testdir/test_mksession.vim @@ -362,6 +362,31 @@ func Test_mksession_buffer_count() set hidden& endfunc +func Test_mksession_buffer_order() + %bwipe! + e Xfoo | e Xbar | e Xbaz | e Xqux + bufdo write + mksession! Xtest_mks.out + + " Verify that loading the session preserves order of buffers + %bwipe! + source Xtest_mks.out + + let s:buf_info = getbufinfo() + call assert_true(s:buf_info[0]['name'] =~# 'Xfoo$') + call assert_true(s:buf_info[1]['name'] =~# 'Xbar$') + call assert_true(s:buf_info[2]['name'] =~# 'Xbaz$') + call assert_true(s:buf_info[3]['name'] =~# 'Xqux$') + + " Clean up. + call delete('Xfoo') + call delete('Xbar') + call delete('Xbaz') + call delete('Xqux') + call delete('Xtest_mks.out') + %bwipe! +endfunc + if has('extra_search') func Test_mksession_hlsearch() diff --git a/src/version.c b/src/version.c index 2bee440e9..b65dac3c5 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4090, +/**/ 4089, /**/ 4088, |