Patch 8.2.4850
Problem:    Mksession mixes up "tabpages" and "curdir" arguments.
Solution:   Correct logic for storing tabpage in session. (closes #10312)
Files:      src/session.c, src/testdir/test_mksession.vim


*** ../vim-8.2.4849/src/session.c       2022-03-29 11:56:57.557660671 +0100
--- src/session.c       2022-04-30 15:39:17.135279912 +0100
***************
*** 623,635 ****
      win_T     *wp;
      char_u    *sname;
      win_T     *edited_win = NULL;
-     int               tabnr;
      int               restore_stal = FALSE;
      win_T     *tab_firstwin;
      frame_T   *tab_topframe;
      int               cur_arg_idx = 0;
      int               next_arg_idx = 0;
      int               ret = FAIL;
  #ifdef FEAT_TERMINAL
      hashtab_T terminal_bufs;
  
--- 623,635 ----
      win_T     *wp;
      char_u    *sname;
      win_T     *edited_win = NULL;
      int               restore_stal = FALSE;
      win_T     *tab_firstwin;
      frame_T   *tab_topframe;
      int               cur_arg_idx = 0;
      int               next_arg_idx = 0;
      int               ret = FAIL;
+     tabpage_T *tp;
  #ifdef FEAT_TERMINAL
      hashtab_T terminal_bufs;
  
***************
*** 755,772 ****
        restore_stal = TRUE;
      }
  
-     // May repeat putting Windows for each tab, when "tabpages" is in
-     // 'sessionoptions'.
-     // Don't use goto_tabpage(), it may change directory and trigger
-     // autocommands.
-     tab_firstwin = firstwin;  // first window in tab page "tabnr"
-     tab_topframe = topframe;
      if ((ssop_flags & SSOP_TABPAGES))
      {
!       tabpage_T *tp;
! 
!       // 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)
            // Use `bufhidden=wipe` to remove empty "placeholder" buffers once
            // they are not needed. This prevents creating extra buffers (see
--- 755,765 ----
        restore_stal = TRUE;
      }
  
      if ((ssop_flags & SSOP_TABPAGES))
      {
!       // "tabpages" is in 'sessionoptions': 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)
            // Use `bufhidden=wipe` to remove empty "placeholder" buffers once
            // they are not needed. This prevents creating extra buffers (see
***************
*** 777,794 ****
        if (first_tabpage->tp_next != NULL && put_line(fd, "tabrewind") == FAIL)
            goto fail;
      }
!     for (tabnr = 1; ; ++tabnr)
      {
-       tabpage_T *tp = NULL;
        int     need_tabnext = FALSE;
        int     cnr = 1;
  
        if ((ssop_flags & SSOP_TABPAGES))
        {
-           tp = find_tabpage(tabnr);
- 
-           if (tp == NULL)
-               break;          // done all tab pages
            if (tp == curtab)
            {
                tab_firstwin = firstwin;
--- 770,789 ----
        if (first_tabpage->tp_next != NULL && put_line(fd, "tabrewind") == FAIL)
            goto fail;
      }
! 
!     // Assume "tabpages" is in 'sessionoptions'.  If not then we only do
!     // "curtab" and bail out of the loop.
!     FOR_ALL_TABPAGES(tp)
      {
        int     need_tabnext = FALSE;
        int     cnr = 1;
  
+       // May repeat putting Windows for each tab, when "tabpages" is in
+       // 'sessionoptions'.
+       // Don't use goto_tabpage(), it may change directory and trigger
+       // autocommands.
        if ((ssop_flags & SSOP_TABPAGES))
        {
            if (tp == curtab)
            {
                tab_firstwin = firstwin;
***************
*** 799,807 ****
                tab_firstwin = tp->tp_firstwin;
                tab_topframe = tp->tp_topframe;
            }
!           if (tabnr > 1)
                need_tabnext = TRUE;
        }
  
        // Before creating the window layout, try loading one file.  If this
        // is aborted we don't end up with a number of useless windows.
--- 794,808 ----
                tab_firstwin = tp->tp_firstwin;
                tab_topframe = tp->tp_topframe;
            }
!           if (tp != first_tabpage)
                need_tabnext = TRUE;
        }
+       else
+       {
+           tp = curtab;
+           tab_firstwin = firstwin;
+           tab_topframe = topframe;
+       }
  
        // Before creating the window layout, try loading one file.  If this
        // is aborted we don't end up with a number of useless windows.
***************
*** 893,903 ****
        // Restore the tab-local working directory if specified
        // Do this before the windows, so that the window-local directory can
        // override the tab-local directory.
!       if (tp != NULL && tp->tp_localdir != NULL && ssop_flags & SSOP_CURDIR)
        {
            if (fputs("tcd ", fd) < 0
!                   || ses_put_fname(fd, tp->tp_localdir, &ssop_flags) == FAIL
!                   || put_eol(fd) == FAIL)
                goto fail;
            did_lcd = TRUE;
        }
--- 894,904 ----
        // Restore the tab-local working directory if specified
        // Do this before the windows, so that the window-local directory can
        // override the tab-local directory.
!       if ((ssop_flags & SSOP_CURDIR) && tp->tp_localdir != NULL)
        {
            if (fputs("tcd ", fd) < 0
!                    || ses_put_fname(fd, tp->tp_localdir, &ssop_flags) == FAIL
!                    || put_eol(fd) == FAIL)
                goto fail;
            did_lcd = TRUE;
        }
*** ../vim-8.2.4849/src/testdir/test_mksession.vim      2022-03-29 
11:56:57.557660671 +0100
--- src/testdir/test_mksession.vim      2022-04-30 15:28:19.823694637 +0100
***************
*** 865,870 ****
--- 865,898 ----
    call delete('Xproj', 'rf')
  endfunc
  
+ " Test for saving and restoring the tab-local working directory when there is
+ " only a single tab and 'tabpages' is not in 'sessionoptions'.
+ func Test_mksession_tcd_single_tabs()
+   only | tabonly
+ 
+   let save_cwd = getcwd()
+   set sessionoptions-=tabpages
+   set sessionoptions+=curdir
+   call mkdir('Xtopdir1')
+   call mkdir('Xtopdir2')
+ 
+   " There are two tab pages, the current one has local cwd set to 'Xtopdir2'.
+   exec 'tcd ' .. save_cwd .. '/Xtopdir1'
+   tabnew
+   exec 'tcd ' .. save_cwd .. '/Xtopdir2'
+   mksession! Xtest_tcd_single
+ 
+   source Xtest_tcd_single
+   call assert_equal(2, haslocaldir())
+   call assert_equal('Xtopdir2', fnamemodify(getcwd(-1, 0), ':t'))
+   %bwipe
+ 
+   set sessionoptions&
+   call chdir(save_cwd)
+   call delete('Xtopdir1', 'rf')
+   call delete('Xtopdir2', 'rf')
+ endfunc
+ 
  " Test for storing the 'lines' and 'columns' settings
  func Test_mksession_resize()
    mksession! Xtest_mks1.out
*** ../vim-8.2.4849/src/version.c       2022-04-30 15:10:03.100515465 +0100
--- src/version.c       2022-04-30 15:30:52.735530158 +0100
***************
*** 748,749 ****
--- 748,751 ----
  {   /* Add new patch number below this line */
+ /**/
+     4850,
  /**/

-- 
Where do you want to crash today?

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
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].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220430151201.A24741C191E%40moolenaar.net.

Raspunde prin e-mail lui