diff options
-rw-r--r-- | src/autocmd.c | 11 | ||||
-rw-r--r-- | src/proto/window.pro | 1 | ||||
-rw-r--r-- | src/structs.h | 1 | ||||
-rw-r--r-- | src/testdir/test_autocmd.vim | 43 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/window.c | 9 |
6 files changed, 62 insertions, 5 deletions
diff --git a/src/autocmd.c b/src/autocmd.c index b1c74cb853..666cf45d30 100644 --- a/src/autocmd.c +++ b/src/autocmd.c @@ -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; diff --git a/src/proto/window.pro b/src/proto/window.pro index 9e66db5a7f..26c7040b8a 100644 --- a/src/proto/window.pro +++ b/src/proto/window.pro @@ -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); diff --git a/src/structs.h b/src/structs.h index 3ce13ff0fb..f9a72e1454 100644 --- a/src/structs.h +++ b/src/structs.h @@ -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 diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index 50fdc41dc1..c7d2534a28 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -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. diff --git a/src/version.c b/src/version.c index 3b33ab176f..6d9a18c109 100644 --- a/src/version.c +++ b/src/version.c @@ -705,6 +705,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 272, +/**/ 271, /**/ 270, diff --git a/src/window.c b/src/window.c index 9ffca77c92..7d78b5f29a 100644 --- a/src/window.c +++ b/src/window.c @@ -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); |