forked from aniani/vim
patch 8.2.0909: cannot go back to the previous local directory
Problem: Cannot go back to the previous local directory. Solution: Add "tcd -" and "lcd -". (Yegappan Lakshmanan, closes #4362)
This commit is contained in:
@@ -1326,6 +1326,10 @@ present in 'cpoptions' and "!" is not used in the command.
|
|||||||
*:tch* *:tchdir*
|
*:tch* *:tchdir*
|
||||||
:tch[dir][!] Same as |:tcd|.
|
:tch[dir][!] Same as |:tcd|.
|
||||||
|
|
||||||
|
*:tcd-*
|
||||||
|
:tcd[!] - Change to the previous current directory, before the
|
||||||
|
last ":tcd {path}" command.
|
||||||
|
|
||||||
*:lc* *:lcd*
|
*:lc* *:lcd*
|
||||||
:lc[d][!] {path} Like |:cd|, but only set the current directory when
|
:lc[d][!] {path} Like |:cd|, but only set the current directory when
|
||||||
the cursor is in the current window. The current
|
the cursor is in the current window. The current
|
||||||
@@ -1335,6 +1339,10 @@ present in 'cpoptions' and "!" is not used in the command.
|
|||||||
*:lch* *:lchdir*
|
*:lch* *:lchdir*
|
||||||
:lch[dir][!] Same as |:lcd|.
|
:lch[dir][!] Same as |:lcd|.
|
||||||
|
|
||||||
|
*:lcd-*
|
||||||
|
:lcd[!] - Change to the previous current directory, before the
|
||||||
|
last ":lcd {path}" command.
|
||||||
|
|
||||||
*:pw* *:pwd* *E187*
|
*:pw* *:pwd* *E187*
|
||||||
:pw[d] Print the current directory name.
|
:pw[d] Print the current directory name.
|
||||||
Also see |getcwd()|.
|
Also see |getcwd()|.
|
||||||
|
@@ -6581,6 +6581,19 @@ free_cd_dir(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#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.
|
* 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_TABPAGE then this was after an ":tcd" command.
|
||||||
@@ -6595,10 +6608,13 @@ post_chdir(cdscope_T scope)
|
|||||||
VIM_CLEAR(curwin->w_localdir);
|
VIM_CLEAR(curwin->w_localdir);
|
||||||
if (scope != CDSCOPE_GLOBAL)
|
if (scope != CDSCOPE_GLOBAL)
|
||||||
{
|
{
|
||||||
// If still in global directory, need to remember current
|
char_u *pdir = get_prevdir(scope);
|
||||||
// directory as global directory.
|
|
||||||
if (globaldir == NULL && prev_dir != NULL)
|
// If still in the global directory, need to remember current
|
||||||
globaldir = vim_strsave(prev_dir);
|
// directory as the global directory.
|
||||||
|
if (globaldir == NULL && pdir != NULL)
|
||||||
|
globaldir = vim_strsave(pdir);
|
||||||
|
|
||||||
// Remember this local directory for the window.
|
// Remember this local directory for the window.
|
||||||
if (mch_dirname(NameBuff, MAXPATHL) == OK)
|
if (mch_dirname(NameBuff, MAXPATHL) == OK)
|
||||||
{
|
{
|
||||||
@@ -6610,8 +6626,7 @@ post_chdir(cdscope_T scope)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We are now in the global directory, no need to remember its
|
// We are now in the global directory, no need to remember its name.
|
||||||
// name.
|
|
||||||
VIM_CLEAR(globaldir);
|
VIM_CLEAR(globaldir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6633,6 +6648,7 @@ changedir_func(
|
|||||||
cdscope_T scope)
|
cdscope_T scope)
|
||||||
{
|
{
|
||||||
char_u *tofree;
|
char_u *tofree;
|
||||||
|
char_u *pdir = NULL;
|
||||||
int dir_differs;
|
int dir_differs;
|
||||||
int retval = FALSE;
|
int retval = FALSE;
|
||||||
|
|
||||||
@@ -6648,20 +6664,29 @@ changedir_func(
|
|||||||
// ":cd -": Change to previous directory
|
// ":cd -": Change to previous directory
|
||||||
if (STRCMP(new_dir, "-") == 0)
|
if (STRCMP(new_dir, "-") == 0)
|
||||||
{
|
{
|
||||||
if (prev_dir == NULL)
|
pdir = get_prevdir(scope);
|
||||||
|
if (pdir == NULL)
|
||||||
{
|
{
|
||||||
emsg(_("E186: No previous directory"));
|
emsg(_("E186: No previous directory"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
new_dir = prev_dir;
|
new_dir = pdir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free the previous directory
|
||||||
|
tofree = get_prevdir(scope);
|
||||||
|
|
||||||
// Save current directory for next ":cd -"
|
// Save current directory for next ":cd -"
|
||||||
tofree = prev_dir;
|
|
||||||
if (mch_dirname(NameBuff, MAXPATHL) == OK)
|
if (mch_dirname(NameBuff, MAXPATHL) == OK)
|
||||||
prev_dir = vim_strsave(NameBuff);
|
pdir = vim_strsave(NameBuff);
|
||||||
else
|
else
|
||||||
prev_dir = NULL;
|
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)
|
#if defined(UNIX) || defined(VMS)
|
||||||
// for UNIX ":cd" means: go to home directory
|
// for UNIX ":cd" means: go to home directory
|
||||||
@@ -6682,8 +6707,8 @@ changedir_func(
|
|||||||
new_dir = NameBuff;
|
new_dir = NameBuff;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
dir_differs = new_dir == NULL || prev_dir == NULL
|
dir_differs = new_dir == NULL || pdir == NULL
|
||||||
|| pathcmp((char *)prev_dir, (char *)new_dir, -1) != 0;
|
|| pathcmp((char *)pdir, (char *)new_dir, -1) != 0;
|
||||||
if (new_dir == NULL || (dir_differs && vim_chdir(new_dir)))
|
if (new_dir == NULL || (dir_differs && vim_chdir(new_dir)))
|
||||||
emsg(_(e_failed));
|
emsg(_(e_failed));
|
||||||
else
|
else
|
||||||
|
@@ -726,6 +726,7 @@ f_chdir(typval_T *argvars, typval_T *rettv)
|
|||||||
|
|
||||||
if (argvars[0].v_type != VAR_STRING)
|
if (argvars[0].v_type != VAR_STRING)
|
||||||
// Returning an empty string means it failed.
|
// Returning an empty string means it failed.
|
||||||
|
// No error message, for historic reasons.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Return the current directory
|
// Return the current directory
|
||||||
|
@@ -2994,6 +2994,8 @@ struct tabpage_S
|
|||||||
|
|
||||||
char_u *tp_localdir; // absolute path of local directory or
|
char_u *tp_localdir; // absolute path of local directory or
|
||||||
// NULL
|
// NULL
|
||||||
|
char_u *tp_prevdir; // previous directory
|
||||||
|
|
||||||
#ifdef FEAT_DIFF
|
#ifdef FEAT_DIFF
|
||||||
diff_T *tp_first_diff;
|
diff_T *tp_first_diff;
|
||||||
buf_T *(tp_diffbuf[DB_COUNT]);
|
buf_T *(tp_diffbuf[DB_COUNT]);
|
||||||
@@ -3397,6 +3399,7 @@ struct window_S
|
|||||||
|
|
||||||
char_u *w_localdir; // absolute path of local directory or
|
char_u *w_localdir; // absolute path of local directory or
|
||||||
// NULL
|
// NULL
|
||||||
|
char_u *w_prevdir; // previous directory
|
||||||
#ifdef FEAT_MENU
|
#ifdef FEAT_MENU
|
||||||
vimmenu_T *w_winbar; // The root of the WinBar menu hierarchy.
|
vimmenu_T *w_winbar; // The root of the WinBar menu hierarchy.
|
||||||
winbar_item_T *w_winbar_items; // list of items in the WinBar
|
winbar_item_T *w_winbar_items; // list of items in the WinBar
|
||||||
|
@@ -129,6 +129,69 @@ func Test_chdir_func()
|
|||||||
call delete('Xdir', 'rf')
|
call delete('Xdir', 'rf')
|
||||||
endfunc
|
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()
|
func Test_cd_completion()
|
||||||
call mkdir('XComplDir1', 'p')
|
call mkdir('XComplDir1', 'p')
|
||||||
call mkdir('XComplDir2', 'p')
|
call mkdir('XComplDir2', 'p')
|
||||||
|
@@ -746,6 +746,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
909,
|
||||||
/**/
|
/**/
|
||||||
908,
|
908,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -3809,6 +3809,7 @@ free_tabpage(tabpage_T *tp)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
vim_free(tp->tp_localdir);
|
vim_free(tp->tp_localdir);
|
||||||
|
vim_free(tp->tp_prevdir);
|
||||||
|
|
||||||
#ifdef FEAT_PYTHON
|
#ifdef FEAT_PYTHON
|
||||||
python_tabpage_free(tp);
|
python_tabpage_free(tp);
|
||||||
@@ -4974,6 +4975,7 @@ win_free(
|
|||||||
vim_free(wp->w_tagstack[i].user_data);
|
vim_free(wp->w_tagstack[i].user_data);
|
||||||
}
|
}
|
||||||
vim_free(wp->w_localdir);
|
vim_free(wp->w_localdir);
|
||||||
|
vim_free(wp->w_prevdir);
|
||||||
|
|
||||||
// Remove the window from the b_wininfo lists, it may happen that the
|
// Remove the window from the b_wininfo lists, it may happen that the
|
||||||
// freed memory is re-used for another window.
|
// freed memory is re-used for another window.
|
||||||
|
Reference in New Issue
Block a user