mirror of
https://github.com/vim/vim.git
synced 2025-09-26 04:04:07 -04:00
patch 9.1.0272: autocmd may change cwd after :tcd and :lcd
Problem: Autocommand may change currect directory after :tcd and :lcd. Solution: Also clear tp_localdir and w_localdir when using aucmd_win. (zeertzjq) closes: #14435 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
a44ced5763
commit
9d956ee8ea
@@ -1660,6 +1660,11 @@ aucmd_prepbuf(
|
||||
|
||||
win_init_popup_win(auc_win, buf);
|
||||
|
||||
// Make sure tp_localdir and globaldir are NULL to avoid a
|
||||
// chdir() in win_enter_ext().
|
||||
// win_init_popup_win() has already set w_localdir to NULL.
|
||||
aco->tp_localdir = curtab->tp_localdir;
|
||||
curtab->tp_localdir = NULL;
|
||||
aco->globaldir = globaldir;
|
||||
globaldir = NULL;
|
||||
|
||||
@@ -1773,6 +1778,12 @@ win_found:
|
||||
vars_clear(&awp->w_vars->dv_hashtab); // free all w: variables
|
||||
hash_init(&awp->w_vars->dv_hashtab); // re-use the hashtab
|
||||
#endif
|
||||
// If :lcd has been used in the autocommand window, correct current
|
||||
// directory before restoring tp_localdir and globaldir.
|
||||
if (awp->w_localdir != NULL)
|
||||
win_fix_current_dir();
|
||||
vim_free(curtab->tp_localdir);
|
||||
curtab->tp_localdir = aco->tp_localdir;
|
||||
vim_free(globaldir);
|
||||
globaldir = aco->globaldir;
|
||||
|
||||
|
@@ -57,6 +57,7 @@ tabpage_T *win_find_tabpage(win_T *win);
|
||||
win_T *win_vert_neighbor(tabpage_T *tp, win_T *wp, int up, long count);
|
||||
win_T *win_horz_neighbor(tabpage_T *tp, win_T *wp, int left, long count);
|
||||
void win_enter(win_T *wp, int undo_sync);
|
||||
void win_fix_current_dir(void);
|
||||
win_T *buf_jump_open_win(buf_T *buf);
|
||||
win_T *buf_jump_open_tab(buf_T *buf);
|
||||
int win_unlisted(win_T *wp);
|
||||
|
@@ -4397,6 +4397,7 @@ typedef struct
|
||||
int new_curwin_id; // ID of new curwin
|
||||
int save_prevwin_id; // ID of saved prevwin
|
||||
bufref_T new_curbuf; // new curbuf
|
||||
char_u *tp_localdir; // saved value of tp_localdir
|
||||
char_u *globaldir; // saved value of globaldir
|
||||
int save_VIsual_active; // saved VIsual_active
|
||||
int save_State; // saved State
|
||||
|
@@ -3727,6 +3727,49 @@ func Test_switch_window_in_autocmd_window()
|
||||
call assert_false(bufexists('Xb.txt'))
|
||||
endfunc
|
||||
|
||||
" Test that using the autocommand window doesn't change current directory.
|
||||
func Test_autocmd_window_cwd()
|
||||
let saveddir = getcwd()
|
||||
call mkdir('Xcwd/a/b/c/d', 'pR')
|
||||
|
||||
new Xa.txt
|
||||
tabnew
|
||||
new Xb.txt
|
||||
|
||||
tabprev
|
||||
cd Xcwd
|
||||
call assert_match('/Xcwd$', getcwd())
|
||||
call assert_match('\[global\] .*/Xcwd$', trim(execute('verbose pwd')))
|
||||
|
||||
autocmd BufEnter Xb.txt lcd ./a/b/c/d
|
||||
doautoall BufEnter
|
||||
au! BufEnter
|
||||
call assert_match('/Xcwd$', getcwd())
|
||||
call assert_match('\[global\] .*/Xcwd$', trim(execute('verbose pwd')))
|
||||
|
||||
tabnext
|
||||
cd ./a
|
||||
tcd ./b
|
||||
lcd ./c
|
||||
call assert_match('/Xcwd/a/b/c$', getcwd())
|
||||
call assert_match('\[window\] .*/Xcwd/a/b/c$', trim(execute('verbose pwd')))
|
||||
|
||||
autocmd BufEnter Xa.txt call assert_match('Xcwd/a/b/c$', getcwd())
|
||||
doautoall BufEnter
|
||||
au! BufEnter
|
||||
call assert_match('/Xcwd/a/b/c$', getcwd())
|
||||
call assert_match('\[window\] .*/Xcwd/a/b/c$', trim(execute('verbose pwd')))
|
||||
bwipe!
|
||||
call assert_match('/Xcwd/a/b$', getcwd())
|
||||
call assert_match('\[tabpage\] .*/Xcwd/a/b$', trim(execute('verbose pwd')))
|
||||
bwipe!
|
||||
call assert_match('/Xcwd/a$', getcwd())
|
||||
call assert_match('\[global\] .*/Xcwd/a$', trim(execute('verbose pwd')))
|
||||
bwipe!
|
||||
|
||||
call chdir(saveddir)
|
||||
endfunc
|
||||
|
||||
func Test_bufwipeout_changes_window()
|
||||
" This should not crash, but we don't have any expectations about what
|
||||
" happens, changing window in BufWipeout has unpredictable results.
|
||||
|
@@ -704,6 +704,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
272,
|
||||
/**/
|
||||
271,
|
||||
/**/
|
||||
|
@@ -4437,8 +4437,7 @@ win_init_popup_win(win_T *wp, buf_T *buf)
|
||||
++buf->b_nwindows;
|
||||
win_init_empty(wp); // set cursor and topline to safe values
|
||||
|
||||
// Make sure w_localdir and globaldir are NULL to avoid a chdir() in
|
||||
// win_enter_ext().
|
||||
// Make sure w_localdir is NULL to avoid a chdir() in win_enter_ext().
|
||||
VIM_CLEAR(wp->w_localdir);
|
||||
}
|
||||
|
||||
@@ -5445,8 +5444,8 @@ win_enter(win_T *wp, int undo_sync)
|
||||
* Used after making another window the current one: change directory if
|
||||
* needed.
|
||||
*/
|
||||
static void
|
||||
fix_current_dir(void)
|
||||
void
|
||||
win_fix_current_dir(void)
|
||||
{
|
||||
if (curwin->w_localdir != NULL || curtab->tp_localdir != NULL)
|
||||
{
|
||||
@@ -5567,7 +5566,7 @@ win_enter_ext(win_T *wp, int flags)
|
||||
}
|
||||
#endif
|
||||
|
||||
fix_current_dir();
|
||||
win_fix_current_dir();
|
||||
|
||||
#ifdef FEAT_JOB_CHANNEL
|
||||
entering_window(curwin);
|
||||
|
Reference in New Issue
Block a user