diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-06-05 22:33:42 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-06-05 22:33:42 +0200 |
commit | 002bc79991286934a9593b80635c27d4238cdfc4 (patch) | |
tree | 777b6a2574f8dfe4ac76552a0a8e44ba005e7961 /src | |
parent | 3fffa97159a427067b60c80ed4645e168cc5c4bd (diff) |
patch 8.2.0909: cannot go back to the previous local directoryv8.2.0909
Problem: Cannot go back to the previous local directory.
Solution: Add "tcd -" and "lcd -". (Yegappan Lakshmanan, closes #4362)
Diffstat (limited to 'src')
-rw-r--r-- | src/ex_docmd.c | 51 | ||||
-rw-r--r-- | src/filepath.c | 1 | ||||
-rw-r--r-- | src/structs.h | 3 | ||||
-rw-r--r-- | src/testdir/test_cd.vim | 63 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/window.c | 2 |
6 files changed, 109 insertions, 13 deletions
diff --git a/src/ex_docmd.c b/src/ex_docmd.c index a98dc077d8..3a1a61491b 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -6582,6 +6582,19 @@ free_cd_dir(void) #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,10 +6608,13 @@ post_chdir(cdscope_T scope) 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); + 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,8 +6626,7 @@ post_chdir(cdscope_T scope) } else { - // We are now in the global directory, no need to remember its - // name. + // We are now in the global directory, no need to remember its name. VIM_CLEAR(globaldir); } @@ -6633,6 +6648,7 @@ changedir_func( cdscope_T scope) { char_u *tofree; + char_u *pdir = NULL; int dir_differs; int retval = FALSE; @@ -6648,20 +6664,29 @@ changedir_func( // ":cd -": Change to previous directory if (STRCMP(new_dir, "-") == 0) { - if (prev_dir == NULL) + pdir = get_prevdir(scope); + if (pdir == NULL) { emsg(_("E186: No previous directory")); return FALSE; } - new_dir = prev_dir; + new_dir = pdir; } + // Free the previous directory + tofree = get_prevdir(scope); + // Save current directory for next ":cd -" - tofree = prev_dir; if (mch_dirname(NameBuff, MAXPATHL) == OK) - prev_dir = vim_strsave(NameBuff); + 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 = NULL; + prev_dir = pdir; #if defined(UNIX) || defined(VMS) // for UNIX ":cd" means: go to home directory @@ -6682,8 +6707,8 @@ changedir_func( new_dir = NameBuff; } #endif - dir_differs = new_dir == NULL || prev_dir == NULL - || pathcmp((char *)prev_dir, (char *)new_dir, -1) != 0; + 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 diff --git a/src/filepath.c b/src/filepath.c index ad7b8b03d4..8bc941d354 100644 --- a/src/filepath.c +++ b/src/filepath.c @@ -726,6 +726,7 @@ f_chdir(typval_T *argvars, typval_T *rettv) 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 diff --git a/src/structs.h b/src/structs.h index 8fb14d7598..80b7cff1e5 100644 --- a/src/structs.h +++ b/src/structs.h @@ -2994,6 +2994,8 @@ struct tabpage_S 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,6 +3399,7 @@ struct window_S 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 diff --git a/src/testdir/test_cd.vim b/src/testdir/test_cd.vim index ad25f3a32e..53f9c1081e 100644 --- a/src/testdir/test_cd.vim +++ b/src/testdir/test_cd.vim @@ -129,6 +129,69 @@ func Test_chdir_func() 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') diff --git a/src/version.c b/src/version.c index 20c0e0dec4..5fca34bf29 100644 --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 909, +/**/ 908, /**/ 907, diff --git a/src/window.c b/src/window.c index ede2c6f281..931d86bdf6 100644 --- a/src/window.c +++ b/src/window.c @@ -3809,6 +3809,7 @@ free_tabpage(tabpage_T *tp) #endif vim_free(tp->tp_localdir); + vim_free(tp->tp_prevdir); #ifdef FEAT_PYTHON python_tabpage_free(tp); @@ -4974,6 +4975,7 @@ win_free( 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. |