Skip to content

Commit

Permalink
patch 9.1.0272: autocmd may change cwd after :tcd and :lcd
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
zeertzjq authored and chrisbra committed Apr 7, 2024
1 parent a44ced5 commit 9d956ee
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 5 deletions.
11 changes: 11 additions & 0 deletions src/autocmd.c
Expand Up @@ -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;

Expand Down Expand Up @@ -1773,6 +1778,12 @@ aucmd_restbuf(
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;

Expand Down
1 change: 1 addition & 0 deletions src/proto/window.pro
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/structs.h
Expand Up @@ -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
Expand Down
43 changes: 43 additions & 0 deletions src/testdir/test_autocmd.vim
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -704,6 +704,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
272,
/**/
271,
/**/
Expand Down
9 changes: 4 additions & 5 deletions src/window.c
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 9d956ee

Please sign in to comment.