# HG changeset patch # User Bram Moolenaar # Date 1544971506 -3600 # Node ID 90ab2d3ce11d694bd7ed5efcf8bb53e833ad228d # Parent c43fefb0ab38c3773c896429090df82335cf8d3c patch 8.1.0602: DirChanged is also triggered when directory didn't change commit https://github.com/vim/vim/commit/2caad3fbbdbf1486a176c9f6bfbc3d9be90e09f7 Author: Bram Moolenaar Date: Sun Dec 16 15:38:02 2018 +0100 patch 8.1.0602: DirChanged is also triggered when directory didn't change Problem: DirChanged is also triggered when the directory didn't change. (Daniel Hahler) Solution: Compare the current with the new directory. (closes #3697) diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -9126,8 +9126,9 @@ post_chdir(int local) void ex_cd(exarg_T *eap) { - char_u *new_dir; - char_u *tofree; + char_u *new_dir; + char_u *tofree; + int dir_differs; new_dir = eap->arg; #if !defined(UNIX) && !defined(VMS) @@ -9183,7 +9184,9 @@ ex_cd(exarg_T *eap) new_dir = NameBuff; } #endif - if (new_dir == NULL || vim_chdir(new_dir)) + dir_differs = new_dir == NULL || prev_dir == NULL + || STRCMP(prev_dir, new_dir) != 0; + if (new_dir == NULL || (dir_differs && vim_chdir(new_dir))) EMSG(_(e_failed)); else { @@ -9195,9 +9198,11 @@ ex_cd(exarg_T *eap) /* Echo the new current directory if the command was typed. */ if (KeyTyped || p_verbose >= 5) ex_pwd(eap); - apply_autocmds(EVENT_DIRCHANGED, - is_local_chdir ? (char_u *)"window" : (char_u *)"global", - new_dir, FALSE, curbuf); + + if (dir_differs) + apply_autocmds(EVENT_DIRCHANGED, + is_local_chdir ? (char_u *)"window" : (char_u *)"global", + new_dir, FALSE, curbuf); } vim_free(tofree); } diff --git a/src/misc2.c b/src/misc2.c --- a/src/misc2.c +++ b/src/misc2.c @@ -3390,17 +3390,29 @@ same_directory(char_u *f1, char_u *f2) * Return OK or FAIL. */ int -vim_chdirfile(char_u *fname, char *trigger_autocmd UNUSED) -{ - char_u dir[MAXPATHL]; +vim_chdirfile(char_u *fname, char *trigger_autocmd) +{ + char_u old_dir[MAXPATHL]; + char_u new_dir[MAXPATHL]; int res; - vim_strncpy(dir, fname, MAXPATHL - 1); - *gettail_sep(dir) = NUL; - res = mch_chdir((char *)dir) == 0 ? OK : FAIL; - if (res == OK && trigger_autocmd != NULL) - apply_autocmds(EVENT_DIRCHANGED, (char_u *)trigger_autocmd, - dir, FALSE, curbuf); + if (mch_dirname(old_dir, MAXPATHL) != OK) + *old_dir = NUL; + + vim_strncpy(new_dir, fname, MAXPATHL - 1); + *gettail_sep(new_dir) = NUL; + + if (STRCMP(old_dir, new_dir) == 0) + // nothing to do + res = OK; + else + { + res = mch_chdir((char *)new_dir) == 0 ? OK : FAIL; + + if (res == OK && trigger_autocmd != NULL) + apply_autocmds(EVENT_DIRCHANGED, (char_u *)trigger_autocmd, + new_dir, FALSE, curbuf); + } return res; } #endif diff --git a/src/testdir/test_autochdir.vim b/src/testdir/test_autochdir.vim --- a/src/testdir/test_autochdir.vim +++ b/src/testdir/test_autochdir.vim @@ -8,11 +8,19 @@ func Test_set_filename() let cwd = getcwd() call test_autochdir() set acd + + let s:li = [] + autocmd DirChanged auto call add(s:li, "autocd") + autocmd DirChanged auto call add(s:li, expand("")) + new w samples/Xtest call assert_equal("Xtest", expand('%')) call assert_equal("samples", substitute(getcwd(), '.*/\(\k*\)', '\1', '')) + call assert_equal(["autocd", getcwd()], s:li) + bwipe! + au! DirChanged set noacd exe 'cd ' . cwd call delete('samples/Xtest') diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -1205,13 +1205,16 @@ function s:Before_test_dirchanged() augroup END let s:li = [] let s:dir_this = getcwd() - let s:dir_other = s:dir_this . '/foo' - call mkdir(s:dir_other) + let s:dir_foo = s:dir_this . '/foo' + call mkdir(s:dir_foo) + let s:dir_bar = s:dir_this . '/bar' + call mkdir(s:dir_bar) endfunc function s:After_test_dirchanged() exe 'cd' s:dir_this - call delete(s:dir_other, 'd') + call delete(s:dir_foo, 'd') + call delete(s:dir_bar, 'd') augroup test_dirchanged autocmd! augroup END @@ -1221,10 +1224,12 @@ function Test_dirchanged_global() call s:Before_test_dirchanged() autocmd test_dirchanged DirChanged global call add(s:li, "cd:") autocmd test_dirchanged DirChanged global call add(s:li, expand("")) - exe 'cd' s:dir_other - call assert_equal(["cd:", s:dir_other], s:li) - exe 'lcd' s:dir_other - call assert_equal(["cd:", s:dir_other], s:li) + exe 'cd' s:dir_foo + call assert_equal(["cd:", s:dir_foo], s:li) + exe 'cd' s:dir_foo + call assert_equal(["cd:", s:dir_foo], s:li) + exe 'lcd' s:dir_bar + call assert_equal(["cd:", s:dir_foo], s:li) call s:After_test_dirchanged() endfunc @@ -1232,10 +1237,12 @@ function Test_dirchanged_local() call s:Before_test_dirchanged() autocmd test_dirchanged DirChanged window call add(s:li, "lcd:") autocmd test_dirchanged DirChanged window call add(s:li, expand("")) - exe 'cd' s:dir_other + exe 'cd' s:dir_foo call assert_equal([], s:li) - exe 'lcd' s:dir_other - call assert_equal(["lcd:", s:dir_other], s:li) + exe 'lcd' s:dir_bar + call assert_equal(["lcd:", s:dir_bar], s:li) + exe 'lcd' s:dir_bar + call assert_equal(["lcd:", s:dir_bar], s:li) call s:After_test_dirchanged() endfunc @@ -1250,9 +1257,9 @@ function Test_dirchanged_auto() set acd exe 'cd ..' call assert_equal([], s:li) - exe 'edit ' . s:dir_other . '/Xfile' - call assert_equal(s:dir_other, getcwd()) - call assert_equal(["auto:", s:dir_other], s:li) + exe 'edit ' . s:dir_foo . '/Xfile' + call assert_equal(s:dir_foo, getcwd()) + call assert_equal(["auto:", s:dir_foo], s:li) set noacd bwipe! call s:After_test_dirchanged() diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -800,6 +800,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 602, +/**/ 601, /**/ 600,