changeset 26809:1c22fcc7415c v8.2.3933

patch 8.2.3933: after ":cd" fails ":cd -" is incorrect Commit: https://github.com/vim/vim/commit/3d0abad5bf4fe125e219f1b56c4e8200cb900e2a Author: Richard Doty <richard.a.doty@gmail.com> Date: Wed Dec 29 14:39:08 2021 +0000 patch 8.2.3933: after ":cd" fails ":cd -" is incorrect Problem: After ":cd" fails ":cd -" is incorrect. Solution: Set the previous directory only after successfully changing directory. (Richard Doty, closes #9419, closes #8983)
author Bram Moolenaar <Bram@vim.org>
date Wed, 29 Dec 2021 15:45:03 +0100
parents e83c9271beba
children 9c34e5550c98
files src/ex_docmd.c src/testdir/test_cd.vim src/version.c
diffstat 3 files changed, 25 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -7359,7 +7359,6 @@ changedir_func(
 	int		forceit,
 	cdscope_T	scope)
 {
-    char_u	*tofree;
     char_u	*pdir = NULL;
     int		dir_differs;
     int		retval = FALSE;
@@ -7385,20 +7384,11 @@ changedir_func(
 	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;
 
     // For UNIX ":cd" means: go to home directory.
     // On other systems too if 'cdhome' is set.
@@ -7425,10 +7415,23 @@ changedir_func(
     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));
+	vim_free(pdir);
+    }
     else
     {
 	char_u  *acmd_fname;
+	char_u	**pp;
+
+	if (scope == CDSCOPE_WINDOW)
+	    pp = &curwin->w_prevdir;
+	else if (scope == CDSCOPE_TABPAGE)
+	    pp = &curtab->tp_prevdir;
+	else
+	    pp = &prev_dir;
+	vim_free(*pp);
+	*pp = pdir;
 
 	post_chdir(scope);
 
@@ -7445,7 +7448,6 @@ changedir_func(
 	}
 	retval = TRUE;
     }
-    vim_free(tofree);
 
     return retval;
 }
@@ -7565,9 +7567,9 @@ do_sleep(long msec, int hide_cursor)
 # endif
 
     if (hide_cursor)
-        cursor_sleep();
+	cursor_sleep();
     else
-        cursor_on();
+	cursor_on();
 
     out_flush_cursor(FALSE, FALSE);
     while (!got_int && done < msec)
@@ -7619,7 +7621,7 @@ do_sleep(long msec, int hide_cursor)
 	(void)vpeekc();
 
     if (hide_cursor)
-        cursor_unsleep();
+	cursor_unsleep();
 }
 
 /*
--- a/src/testdir/test_cd.vim
+++ b/src/testdir/test_cd.vim
@@ -44,6 +44,13 @@ func Test_cd_minus()
   cd -
   call assert_equal(path, getcwd())
 
+  " Test for :cd - after a failed :cd
+  call assert_fails('cd /nonexistent', 'E344:')
+  call assert_equal(path, getcwd())
+  cd -
+  call assert_equal(path_dotdot, getcwd())
+  cd -
+
   " Test for :cd - without a previous directory
   let lines =<< trim [SCRIPT]
     call assert_fails('cd -', 'E186:')
--- a/src/version.c
+++ b/src/version.c
@@ -750,6 +750,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3933,
+/**/
     3932,
 /**/
     3931,