Patch 8.2.0909
Problem:    Cannot go back to the previous local directory.
Solution:   Add "tcd -" and "lcd -". (Yegappan Lakshmanan, closes #4362)
Files:      runtime/doc/editing.txt, src/filepath.c, src/ex_docmd.c,
            src/structs.h, src/testdir/test_cd.vim, src/window.c


*** ../vim-8.2.0908/runtime/doc/editing.txt     2020-06-01 16:26:15.338852818 
+0200
--- runtime/doc/editing.txt     2020-06-05 22:28:33.434428568 +0200
***************
*** 1315,1320 ****
--- 1326,1335 ----
                                                        *:tch* *:tchdir*
  :tch[dir][!]          Same as |:tcd|.
  
+                                                       *:tcd-*
+ :tcd[!] -             Change to the previous current directory, before the
+                       last ":tcd {path}" command.
+ 
                                                        *:lc* *:lcd*
  :lc[d][!] {path}      Like |:cd|, but only set the current directory when
                        the cursor is in the current window.  The current
***************
*** 1324,1329 ****
--- 1339,1348 ----
                                                        *:lch* *:lchdir*
  :lch[dir][!]          Same as |:lcd|.
  
+                                                       *:lcd-*
+ :lcd[!] -             Change to the previous current directory, before the
+                       last ":lcd {path}" command.
+ 
                                                        *:pw* *:pwd* *E187*
  :pw[d]                        Print the current directory name.
                        Also see |getcwd()|.
*** ../vim-8.2.0908/src/filepath.c      2020-06-01 16:09:30.266292734 +0200
--- src/filepath.c      2020-06-05 22:20:38.463486225 +0200
***************
*** 726,731 ****
--- 726,732 ----
  
      if (argvars[0].v_type != VAR_STRING)
        // Returning an empty string means it failed.
+       // No error message, for historic reasons.
        return;
  
      // Return the current directory
*** ../vim-8.2.0908/src/ex_docmd.c      2020-06-01 21:13:08.520030259 +0200
--- src/ex_docmd.c      2020-06-05 22:22:52.659212940 +0200
***************
*** 6582,6587 ****
--- 6582,6600 ----
  #endif
  
  /*
+  * Get the previous directory for the given chdir scope.
+  */
+     static char_u *
+ get_prevdir(cdscope_T scope)
+ {
+     if (scope == CDSCOPE_WINDOW)
+       return curwin->w_prevdir;
+     else if (scope == CDSCOPE_TABPAGE)
+       return curtab->tp_prevdir;
+     return prev_dir;
+ }
+ 
+ /*
   * Deal with the side effects of changing the current directory.
   * When 'scope' is CDSCOPE_TABPAGE then this was after an ":tcd" command.
   * When 'scope' is CDSCOPE_WINDOW then this was after an ":lcd" command.
***************
*** 6595,6604 ****
      VIM_CLEAR(curwin->w_localdir);
      if (scope != CDSCOPE_GLOBAL)
      {
!       // If still in global directory, need to remember current
!       // directory as global directory.
!       if (globaldir == NULL && prev_dir != NULL)
!           globaldir = vim_strsave(prev_dir);
        // Remember this local directory for the window.
        if (mch_dirname(NameBuff, MAXPATHL) == OK)
        {
--- 6608,6620 ----
      VIM_CLEAR(curwin->w_localdir);
      if (scope != CDSCOPE_GLOBAL)
      {
!       char_u  *pdir = get_prevdir(scope);
! 
!       // If still in the global directory, need to remember current
!       // directory as the global directory.
!       if (globaldir == NULL && pdir != NULL)
!           globaldir = vim_strsave(pdir);
! 
        // Remember this local directory for the window.
        if (mch_dirname(NameBuff, MAXPATHL) == OK)
        {
***************
*** 6610,6617 ****
      }
      else
      {
!       // We are now in the global directory, no need to remember its
!       // name.
        VIM_CLEAR(globaldir);
      }
  
--- 6626,6632 ----
      }
      else
      {
!       // We are now in the global directory, no need to remember its name.
        VIM_CLEAR(globaldir);
      }
  
***************
*** 6633,6638 ****
--- 6648,6654 ----
        cdscope_T       scope)
  {
      char_u    *tofree;
+     char_u    *pdir = NULL;
      int               dir_differs;
      int               retval = FALSE;
  
***************
*** 6648,6667 ****
      // ":cd -": Change to previous directory
      if (STRCMP(new_dir, "-") == 0)
      {
!       if (prev_dir == NULL)
        {
            emsg(_("E186: No previous directory"));
            return FALSE;
        }
!       new_dir = prev_dir;
      }
  
      // Save current directory for next ":cd -"
-     tofree = prev_dir;
      if (mch_dirname(NameBuff, MAXPATHL) == OK)
!       prev_dir = vim_strsave(NameBuff);
      else
!       prev_dir = NULL;
  
  #if defined(UNIX) || defined(VMS)
      // for UNIX ":cd" means: go to home directory
--- 6664,6692 ----
      // ":cd -": Change to previous directory
      if (STRCMP(new_dir, "-") == 0)
      {
!       pdir = get_prevdir(scope);
!       if (pdir == NULL)
        {
            emsg(_("E186: No previous directory"));
            return FALSE;
        }
!       new_dir = pdir;
      }
  
+     // Free the previous directory
+     tofree = get_prevdir(scope);
+ 
      // Save current directory for next ":cd -"
      if (mch_dirname(NameBuff, MAXPATHL) == OK)
!       pdir = vim_strsave(NameBuff);
!     else
!       pdir = NULL;
!     if (scope == CDSCOPE_WINDOW)
!       curwin->w_prevdir = pdir;
!     else if (scope == CDSCOPE_TABPAGE)
!       curtab->tp_prevdir = pdir;
      else
!       prev_dir = pdir;
  
  #if defined(UNIX) || defined(VMS)
      // for UNIX ":cd" means: go to home directory
***************
*** 6682,6689 ****
        new_dir = NameBuff;
      }
  #endif
!     dir_differs = new_dir == NULL || prev_dir == NULL
!       || pathcmp((char *)prev_dir, (char *)new_dir, -1) != 0;
      if (new_dir == NULL || (dir_differs && vim_chdir(new_dir)))
        emsg(_(e_failed));
      else
--- 6707,6714 ----
        new_dir = NameBuff;
      }
  #endif
!     dir_differs = new_dir == NULL || pdir == NULL
!       || pathcmp((char *)pdir, (char *)new_dir, -1) != 0;
      if (new_dir == NULL || (dir_differs && vim_chdir(new_dir)))
        emsg(_(e_failed));
      else
*** ../vim-8.2.0908/src/structs.h       2020-05-31 19:48:49.314871091 +0200
--- src/structs.h       2020-06-05 22:19:03.447662048 +0200
***************
*** 2994,2999 ****
--- 2994,3001 ----
  
      char_u        *tp_localdir;       // absolute path of local directory or
                                        // NULL
+     char_u        *tp_prevdir;        // previous directory
+ 
  #ifdef FEAT_DIFF
      diff_T        *tp_first_diff;
      buf_T         *(tp_diffbuf[DB_COUNT]);
***************
*** 3397,3402 ****
--- 3399,3405 ----
  
      char_u    *w_localdir;        // absolute path of local directory or
                                    // NULL
+     char_u    *w_prevdir;         // previous directory
  #ifdef FEAT_MENU
      vimmenu_T *w_winbar;          // The root of the WinBar menu hierarchy.
      winbar_item_T *w_winbar_items;  // list of items in the WinBar
*** ../vim-8.2.0908/src/testdir/test_cd.vim     2020-06-01 16:26:15.338852818 
+0200
--- src/testdir/test_cd.vim     2020-06-05 22:25:01.202929740 +0200
***************
*** 129,134 ****
--- 129,197 ----
    call delete('Xdir', 'rf')
  endfunc
  
+ " Test for changing to the previous directory '-'
+ func Test_prev_dir()
+   let topdir = getcwd()
+   call mkdir('Xdir/a/b/c', 'p')
+ 
+   " Create a few tabpages and windows with different directories
+   new | only
+   tabnew | new
+   tabnew
+   tabfirst
+   cd Xdir
+   tabnext | wincmd t
+   tcd a
+   wincmd w
+   lcd b
+   tabnext
+   tcd a/b/c
+ 
+   " Change to the previous directory twice in all the windows.
+   tabfirst
+   cd - | cd -
+   tabnext | wincmd t
+   tcd - | tcd -
+   wincmd w
+   lcd - | lcd -
+   tabnext
+   tcd - | tcd -
+ 
+   " Check the directory of all the windows
+   tabfirst
+   call assert_equal('Xdir', fnamemodify(getcwd(), ':t'))
+   tabnext | wincmd t
+   call assert_equal('a', fnamemodify(getcwd(), ':t'))
+   wincmd w
+   call assert_equal('b', fnamemodify(getcwd(), ':t'))
+   tabnext
+   call assert_equal('c', fnamemodify(getcwd(), ':t'))
+ 
+   " Change to the previous directory using chdir()
+   tabfirst
+   call chdir("-") | call chdir("-")
+   tabnext | wincmd t
+   call chdir("-") | call chdir("-")
+   wincmd w
+   call chdir("-") | call chdir("-")
+   tabnext
+   call chdir("-") | call chdir("-")
+ 
+   " Check the directory of all the windows
+   tabfirst
+   call assert_equal('Xdir', fnamemodify(getcwd(), ':t'))
+   tabnext | wincmd t
+   call assert_equal('a', fnamemodify(getcwd(), ':t'))
+   wincmd w
+   call assert_equal('b', fnamemodify(getcwd(), ':t'))
+   tabnext
+   call assert_equal('c', fnamemodify(getcwd(), ':t'))
+ 
+   only | tabonly
+   call chdir(topdir)
+   call delete('Xdir', 'rf')
+ endfunc
+ 
  func Test_cd_completion()
    call mkdir('XComplDir1', 'p')
    call mkdir('XComplDir2', 'p')
*** ../vim-8.2.0908/src/window.c        2020-05-13 13:40:12.690995638 +0200
--- src/window.c        2020-06-05 22:19:03.451662041 +0200
***************
*** 3809,3814 ****
--- 3809,3815 ----
  #endif
  
      vim_free(tp->tp_localdir);
+     vim_free(tp->tp_prevdir);
  
  #ifdef FEAT_PYTHON
      python_tabpage_free(tp);
***************
*** 4974,4979 ****
--- 4975,4981 ----
        vim_free(wp->w_tagstack[i].user_data);
      }
      vim_free(wp->w_localdir);
+     vim_free(wp->w_prevdir);
  
      // Remove the window from the b_wininfo lists, it may happen that the
      // freed memory is re-used for another window.
*** ../vim-8.2.0908/src/version.c       2020-06-05 21:06:06.607601386 +0200
--- src/version.c       2020-06-05 22:27:10.542628565 +0200
***************
*** 748,749 ****
--- 748,751 ----
  {   /* Add new patch number below this line */
+ /**/
+     909,
  /**/

-- 
The greatest lies of all time:
  (1) The check is in the mail.
  (2) We have a really challenging assignment for you.
  (3) I love you.
  (4) All bugs have been fixed.
  (5) This won't hurt a bit.
  (6) Honey, I just need to debug this program and be home in 5 minutes.
  (7) I have just sent you an e-mail about that.
  (8) Of course I'll respect you in the morning.
  (9) I'm from the government, and I'm here to help you.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            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/202006052034.055KYeZT1097602%40masaka.moolenaar.net.

Raspunde prin e-mail lui