diff options
-rw-r--r-- | src/nvim/ex_docmd.c | 24 | ||||
-rw-r--r-- | src/nvim/file_search.c | 6 | ||||
-rw-r--r-- | test/functional/autocmd/dirchanged_spec.lua | 21 |
3 files changed, 29 insertions, 22 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 146f1b6df6..5ab97d9b9a 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6943,24 +6943,28 @@ void free_cd_dir(void) /// @param scope Scope of the function call (global, tab or window). void post_chdir(CdScope scope) { - // The local directory of the current window is always overwritten. + // Always overwrite the window-local CWD. xfree(curwin->w_localdir); curwin->w_localdir = NULL; - // Overwrite the local directory of the current tab page for `cd` and `tcd` + // Overwrite the tab-local CWD for :cd, :tcd. if (scope >= kCdScopeTab) { xfree(curtab->tp_localdir); curtab->tp_localdir = NULL; } if (scope < kCdScopeGlobal) { - // If still in global directory, need to remember current directory as - // global directory. + // If still in global directory, set CWD as the global directory. if (globaldir == NULL && prev_dir != NULL) { globaldir = vim_strsave(prev_dir); } } + char curdir[MAXPATHL]; + if (os_dirname((char_u *)curdir, MAXPATHL) != OK) { + EMSG2(_(e_intern2), "post_chdir()"); + return; + } switch (scope) { case kCdScopeGlobal: // We are now in the global directory, no need to remember its name. @@ -6968,23 +6972,17 @@ void post_chdir(CdScope scope) globaldir = NULL; break; case kCdScopeTab: - // Remember this local directory for the tab page. - if (os_dirname(NameBuff, MAXPATHL) == OK) { - curtab->tp_localdir = vim_strsave(NameBuff); - } + curtab->tp_localdir = (char_u *)xstrdup(curdir); break; case kCdScopeWindow: - // Remember this local directory for the window. - if (os_dirname(NameBuff, MAXPATHL) == OK) { - curwin->w_localdir = vim_strsave(NameBuff); - } + curwin->w_localdir = (char_u *)xstrdup(curdir); break; case kCdScopeInvalid: - // We should never get here assert(false); } shorten_fnames(TRUE); + do_autocmd_dirchanged(curdir, scope); } /// `:cd`, `:tcd`, `:lcd`, `:chdir`, `:tchdir` and `:lchdir`. diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 79a39c6503..34696ddd7f 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -1519,7 +1519,7 @@ theend: return file_name; } -static void do_autocmd_dirchanged(char_u *new_dir, CdScope scope) +void do_autocmd_dirchanged(char *new_dir, CdScope scope) { static bool recursive = false; @@ -1587,10 +1587,6 @@ int vim_chdir(char_u *new_dir, CdScope scope) } int r = os_chdir((char *)dir_name); - if (r == 0) { - do_autocmd_dirchanged(dir_name, scope); - } - xfree(dir_name); return r; } diff --git a/test/functional/autocmd/dirchanged_spec.lua b/test/functional/autocmd/dirchanged_spec.lua index 15196dbd44..f51a978221 100644 --- a/test/functional/autocmd/dirchanged_spec.lua +++ b/test/functional/autocmd/dirchanged_spec.lua @@ -20,7 +20,9 @@ describe('autocmd DirChanged', function() before_each(function() clear() - command('autocmd DirChanged * let [g:event, g:scope, g:cdcount] = [copy(v:event), expand("<amatch>"), 1 + get(g:, "cdcount", 0)]') + command('autocmd DirChanged * let [g:getcwd_rv, g:event, g:amatch, g:cdcount] ' + ..' = [getcwd(), copy(v:event), expand("<amatch>"), 1 + get(g:, "cdcount", 0)]' + ..[[ | let g:event['cwd'] = substitute(g:event['cwd'], '\\', '/', 'g') ]]) end) it('sets v:event', function() @@ -37,6 +39,17 @@ describe('autocmd DirChanged', function() eq(3, eval('g:cdcount')) end) + it('sets getcwd() during event #6260', function() + command('lcd '..dirs[1]) + eq(dirs[1], eval('g:getcwd_rv')) + + command('tcd '..dirs[2]) + eq(dirs[2], eval('g:getcwd_rv')) + + command('cd '..dirs[3]) + eq(dirs[3], eval('g:getcwd_rv')) + end) + it('disallows recursion', function() command('set shellslash') -- Set up a _nested_ handler. @@ -50,13 +63,13 @@ describe('autocmd DirChanged', function() it('sets <amatch> to CWD "scope"', function() command('lcd '..dirs[1]) - eq('window', eval('g:scope')) + eq('window', eval('g:amatch')) command('tcd '..dirs[2]) - eq('tab', eval('g:scope')) + eq('tab', eval('g:amatch')) command('cd '..dirs[3]) - eq('global', eval('g:scope')) + eq('global', eval('g:amatch')) end) it('does not trigger if :cd fails', function() |