diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-02-11 12:44:47 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-02-11 12:55:58 +0800 |
commit | 059d36e326e31fc9bc6055d7c999f86d94fa9bd5 (patch) | |
tree | 53577f4456663a3315e0d485914c3a4d6c4e2f42 | |
parent | 851252f79ddaaca5456b287342cd36130c76ff38 (diff) | |
download | rneovim-059d36e326e31fc9bc6055d7c999f86d94fa9bd5.tar.gz rneovim-059d36e326e31fc9bc6055d7c999f86d94fa9bd5.tar.bz2 rneovim-059d36e326e31fc9bc6055d7c999f86d94fa9bd5.zip |
feat(events): add DirChangedPre
In Nvim, like DirChanged, this also triggers when switching windows.
This marks Vim patch 8.2.4335 as ported.
vim-patch:8.2.4335: no autocommand event triggered before changing directory
Problem: No autocommand event triggered before changing directory. (Ronnie
Magatti)
Solution: Add DirChangedPre. (closes vim/vim#9721)
https://github.com/vim/vim/commit/28e8f73ae2d90009fd62cd60f97c2643ba44de68
-rw-r--r-- | runtime/doc/autocmd.txt | 15 | ||||
-rw-r--r-- | runtime/doc/vim_diff.txt | 3 | ||||
-rw-r--r-- | src/nvim/auevents.lua | 5 | ||||
-rw-r--r-- | src/nvim/autocmd.c | 14 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 15 | ||||
-rw-r--r-- | src/nvim/file_search.c | 21 | ||||
-rw-r--r-- | src/nvim/testdir/test_autocmd.vim | 12 | ||||
-rw-r--r-- | src/nvim/window.c | 23 | ||||
-rw-r--r-- | test/functional/autocmd/dirchanged_spec.lua | 128 |
9 files changed, 182 insertions, 54 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index ed75acf36e..dbe70b84cf 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -525,8 +525,19 @@ DirChanged After the |current-directory| was changed. "global" to trigger on `:cd` "auto" to trigger on 'autochdir'. Sets these |v:event| keys: - cwd: current working directory - scope: "global", "tabpage", "window" + cwd: current working directory + scope: "global", "tabpage", "window" + changed_window: v:true if we fired the event + switching window (or tab) + <afile> is set to the new directory name. + Non-recursive (event cannot trigger itself). + *DirChangedPre* +DirChangedPre When the |current-directory| is going to be + changed, as with |DirChanged|. + The pattern is like with |DirChanged|. + Sets these |v:event| keys: + directory: new working directory + scope: "global", "tabpage", "window" changed_window: v:true if we fired the event switching window (or tab) <afile> is set to the new directory name. diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 7892b82137..385ce34d70 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -433,7 +433,8 @@ Vimscript compatibility: `this_session` does not alias to |v:this_session| Working directory (Vim implemented some of these later than Nvim): -- |DirChanged| can be triggered when switching to another window. +- |DirChanged| and |DirChangedPre| can be triggered when switching to another + window or tab. - |getcwd()| and |haslocaldir()| may throw errors if the tab page or window cannot be found. *E5000* *E5001* *E5002* - |haslocaldir()| checks for tab-local directory if and only if -1 is passed as diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index 8fe623fc96..518d0b52b2 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -40,6 +40,7 @@ return { 'DiagnosticChanged', -- diagnostics in a buffer were modified 'DiffUpdated', -- diffs have been updated 'DirChanged', -- directory changed + 'DirChangedPre', -- directory is going to change 'EncodingChanged', -- after changing the 'encoding' option 'ExitPre', -- before exiting 'FileAppendCmd', -- append to a file using command @@ -132,18 +133,14 @@ return { nvim_specific = { BufModifiedSet=true, DiagnosticChanged=true, - DirChanged=true, RecordingEnter=true, RecordingLeave=true, Signal=true, - TabClosed=true, - TabNew=true, TabNewEntered=true, TermClose=true, TermOpen=true, UIEnter=true, UILeave=true, - WinClosed=true, WinScrolled=true, }, } diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index dfba18b11d..6dc614813b 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -1517,13 +1517,13 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, || event == EVENT_CMDLINELEAVE || event == EVENT_CMDWINENTER || event == EVENT_CMDWINLEAVE || event == EVENT_CMDUNDEFINED || event == EVENT_COLORSCHEME || event == EVENT_COLORSCHEMEPRE - || event == EVENT_DIRCHANGED || event == EVENT_FILETYPE - || event == EVENT_FUNCUNDEFINED || event == EVENT_MODECHANGED - || event == EVENT_OPTIONSET || event == EVENT_QUICKFIXCMDPOST - || event == EVENT_QUICKFIXCMDPRE || event == EVENT_REMOTEREPLY - || event == EVENT_SPELLFILEMISSING || event == EVENT_SYNTAX - || event == EVENT_SIGNAL || event == EVENT_TABCLOSED - || event == EVENT_WINCLOSED) { + || event == EVENT_DIRCHANGED || event == EVENT_DIRCHANGEDPRE + || event == EVENT_FILETYPE || event == EVENT_FUNCUNDEFINED + || event == EVENT_MODECHANGED || event == EVENT_OPTIONSET + || event == EVENT_QUICKFIXCMDPOST || event == EVENT_QUICKFIXCMDPRE + || event == EVENT_REMOTEREPLY || event == EVENT_SPELLFILEMISSING + || event == EVENT_SYNTAX || event == EVENT_SIGNAL + || event == EVENT_TABCLOSED || event == EVENT_WINCLOSED) { fname = vim_strsave(fname); } else { fname = (char_u *)FullName_save((char *)fname, false); diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index d884838136..8b6d7b91a8 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -7784,7 +7784,7 @@ static char_u *get_prevdir(CdScope scope) /// Deal with the side effects of changing the current directory. /// /// @param scope Scope of the function call (global, tab or window). -void post_chdir(CdScope scope, bool trigger_dirchanged) +static void post_chdir(CdScope scope, bool trigger_dirchanged) { // Always overwrite the window-local CWD. XFREE_CLEAR(curwin->w_localdir); @@ -7825,7 +7825,7 @@ void post_chdir(CdScope scope, bool trigger_dirchanged) shorten_fnames(true); if (trigger_dirchanged) { - do_autocmd_dirchanged(cwd, scope, kCdCauseManual); + do_autocmd_dirchanged(cwd, scope, kCdCauseManual, false); } } @@ -7869,10 +7869,13 @@ bool changedir_func(char_u *new_dir, CdScope scope) } bool dir_differs = pdir == NULL || pathcmp((char *)pdir, (char *)new_dir, -1) != 0; - if (dir_differs && vim_chdir(new_dir) != 0) { - emsg(_(e_failed)); - xfree(pdir); - return false; + if (dir_differs) { + do_autocmd_dirchanged((char *)new_dir, scope, kCdCauseManual, true); + if (vim_chdir(new_dir) != 0) { + emsg(_(e_failed)); + xfree(pdir); + return false; + } } char_u **pp; diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 25dbf680de..d0f7a91d6c 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -1600,11 +1600,13 @@ theend: return file_name; } -void do_autocmd_dirchanged(char *new_dir, CdScope scope, CdCause cause) +void do_autocmd_dirchanged(char *new_dir, CdScope scope, CdCause cause, bool pre) { static bool recursive = false; - if (recursive || !has_event(EVENT_DIRCHANGED)) { + event_T event = pre ? EVENT_DIRCHANGEDPRE : EVENT_DIRCHANGED; + + if (recursive || !has_event(event)) { // No autocommand was defined or we changed // the directory from this autocommand. return; @@ -1638,8 +1640,12 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, CdCause cause) new_dir = new_dir_buf; #endif + if (pre) { + tv_dict_add_str(dict, S_LEN("directory"), new_dir); + } else { + tv_dict_add_str(dict, S_LEN("cwd"), new_dir); + } tv_dict_add_str(dict, S_LEN("scope"), buf); // -V614 - tv_dict_add_str(dict, S_LEN("cwd"), new_dir); tv_dict_add_bool(dict, S_LEN("changed_window"), cause == kCdCauseWindow); tv_dict_set_keys_readonly(dict); @@ -1655,8 +1661,7 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, CdCause cause) abort(); } - apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, (char_u *)new_dir, false, - curbuf); + apply_autocmds(event, (char_u *)buf, (char_u *)new_dir, false, curbuf); restore_v_event(dict, &save_v_event); @@ -1682,12 +1687,16 @@ int vim_chdirfile(char_u *fname, CdCause cause) return OK; } + if (cause != kCdCauseOther) { + do_autocmd_dirchanged(dir, kCdScopeWindow, cause, true); + } + if (os_chdir(dir) != 0) { return FAIL; } if (cause != kCdCauseOther) { - do_autocmd_dirchanged(dir, kCdScopeWindow, cause); + do_autocmd_dirchanged(dir, kCdScopeWindow, cause, false); } return OK; diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index a8d51ef598..82e8f9ba77 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -1850,14 +1850,16 @@ endfunc function Test_dirchanged_global() call s:Before_test_dirchanged() + autocmd test_dirchanged DirChangedPre global call add(s:li, "pre cd " .. v:event.directory) autocmd test_dirchanged DirChanged global call add(s:li, "cd:") autocmd test_dirchanged DirChanged global call add(s:li, expand("<afile>")) call chdir(s:dir_foo) - call assert_equal(["cd:", s:dir_foo], s:li) + let expected = ["pre cd " .. s:dir_foo, "cd:", s:dir_foo] + call assert_equal(expected, s:li) call chdir(s:dir_foo) - call assert_equal(["cd:", s:dir_foo], s:li) + call assert_equal(expected, s:li) exe 'lcd ' .. fnameescape(s:dir_bar) - call assert_equal(["cd:", s:dir_foo], s:li) + call assert_equal(expected, s:li) call s:After_test_dirchanged() endfunc @@ -1879,6 +1881,7 @@ function Test_dirchanged_auto() CheckOption autochdir call s:Before_test_dirchanged() call test_autochdir() + autocmd test_dirchanged DirChangedPre auto call add(s:li, "pre cd " .. v:event.directory) autocmd test_dirchanged DirChanged auto call add(s:li, "auto:") autocmd test_dirchanged DirChanged auto call add(s:li, expand("<afile>")) set acd @@ -1886,7 +1889,8 @@ function Test_dirchanged_auto() call assert_equal([], s:li) exe 'edit ' . s:dir_foo . '/Xfile' call assert_equal(s:dir_foo, getcwd()) - call assert_equal(["auto:", s:dir_foo], s:li) + let expected = ["pre cd " .. s:dir_foo, "auto:", s:dir_foo] + call assert_equal(expected, s:li) set noacd bwipe! call s:After_test_dirchanged() diff --git a/src/nvim/window.c b/src/nvim/window.c index 6996a93928..83495801e8 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4645,20 +4645,29 @@ void fix_current_dir(void) globaldir = (char_u *)xstrdup(cwd); } } + bool dir_differs = pathcmp(new_dir, cwd, -1) != 0; + if (!p_acd && dir_differs) { + do_autocmd_dirchanged(new_dir, curwin->w_localdir ? kCdScopeWindow : kCdScopeTabpage, + kCdCauseWindow, true); + } if (os_chdir(new_dir) == 0) { - if (!p_acd && pathcmp(new_dir, cwd, -1) != 0) { - do_autocmd_dirchanged(new_dir, curwin->w_localdir - ? kCdScopeWindow : kCdScopeTabpage, kCdCauseWindow); + if (!p_acd && dir_differs) { + do_autocmd_dirchanged(new_dir, curwin->w_localdir ? kCdScopeWindow : kCdScopeTabpage, + kCdCauseWindow, false); } - last_chdir_reason = NULL; - shorten_fnames(true); } + last_chdir_reason = NULL; + shorten_fnames(true); } else if (globaldir != NULL) { // Window doesn't have a local directory and we are not in the global // directory: Change to the global directory. + bool dir_differs = pathcmp((char *)globaldir, cwd, -1) != 0; + if (!p_acd && dir_differs) { + do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, kCdCauseWindow, true); + } if (os_chdir((char *)globaldir) == 0) { - if (!p_acd && pathcmp((char *)globaldir, cwd, -1) != 0) { - do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, kCdCauseWindow); + if (!p_acd && dir_differs) { + do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, kCdCauseWindow, false); } } XFREE_CLEAR(globaldir); diff --git a/test/functional/autocmd/dirchanged_spec.lua b/test/functional/autocmd/dirchanged_spec.lua index f4a1642ebf..45dc06b39b 100644 --- a/test/functional/autocmd/dirchanged_spec.lua +++ b/test/functional/autocmd/dirchanged_spec.lua @@ -8,7 +8,7 @@ local eval = h.eval local request = h.request local iswin = h.iswin -describe('autocmd DirChanged', function() +describe('autocmd DirChanged and DirChangedPre', function() local curdir = string.gsub(lfs.currentdir(), '\\', '/') local dirs = { curdir .. '/Xtest-functional-autocmd-dirchanged.dir1', @@ -26,31 +26,43 @@ describe('autocmd DirChanged', function() before_each(function() clear() + command('autocmd DirChangedPre * let [g:evpre, g:amatchpre, g:cdprecount] ' + ..'= [copy(v:event), expand("<amatch>"), 1 + get(g:, "cdprecount", 0)]') command('autocmd DirChanged * let [g:getcwd, g:ev, g:amatch, g:cdcount] ' - ..' = [getcwd(), copy(v:event), expand("<amatch>"), 1 + get(g:, "cdcount", 0)]') + ..'= [getcwd(), copy(v:event), expand("<amatch>"), 1 + get(g:, "cdcount", 0)]') -- Normalize path separators. + command([[autocmd DirChangedPre * let g:evpre['directory'] = substitute(g:evpre['directory'], '\\', '/', 'g')]]) command([[autocmd DirChanged * let g:ev['cwd'] = substitute(g:ev['cwd'], '\\', '/', 'g')]]) - command([[autocmd DirChanged * let g:getcwd = substitute(g:getcwd, '\\', '/', 'g')]]) + command([[autocmd DirChanged * let g:getcwd = substitute(g:getcwd, '\\', '/', 'g')]]) end) - it('sets v:event and <amatch>', function() + it('set v:event and <amatch>', function() command('lcd '..dirs[1]) + eq({directory=dirs[1], scope='window', changed_window=false}, eval('g:evpre')) eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev')) + eq('window', eval('g:amatchpre')) eq('window', eval('g:amatch')) + eq(1, eval('g:cdprecount')) eq(1, eval('g:cdcount')) command('tcd '..dirs[2]) + eq({directory=dirs[2], scope='tabpage', changed_window=false}, eval('g:evpre')) eq({cwd=dirs[2], scope='tabpage', changed_window=false}, eval('g:ev')) + eq('tabpage', eval('g:amatchpre')) eq('tabpage', eval('g:amatch')) + eq(2, eval('g:cdprecount')) eq(2, eval('g:cdcount')) command('cd '..dirs[3]) + eq({directory=dirs[3], scope='global', changed_window=false}, eval('g:evpre')) eq({cwd=dirs[3], scope='global', changed_window=false}, eval('g:ev')) + eq('global', eval('g:amatchpre')) eq('global', eval('g:amatch')) + eq(3, eval('g:cdprecount')) eq(3, eval('g:cdcount')) end) - it('sets getcwd() during event #6260', function() + it('DirChanged set getcwd() during event #6260', function() command('lcd '..dirs[1]) eq(dirs[1], eval('g:getcwd')) @@ -61,7 +73,7 @@ describe('autocmd DirChanged', function() eq(dirs[3], eval('g:getcwd')) end) - it('disallows recursion', function() + it('disallow recursion', function() command('set shellslash') -- Set up a _nested_ handler. command('autocmd DirChanged * nested lcd '..dirs[3]) @@ -72,23 +84,36 @@ describe('autocmd DirChanged', function() eq(dirs[3], eval('getcwd()')) end) - it('does not trigger if :cd fails', function() + it('only DirChangedPre is triggered if :cd fails', function() command('let g:ev = {}') + command('let g:cdcount = 0') local status1, err1 = pcall(function() - command('lcd '..dirs[1] .. '/doesnotexist') + command('lcd '..dirs[1]..'/doesnotexist') end) + eq({directory=dirs[1]..'/doesnotexist', scope='window', changed_window=false}, eval('g:evpre')) eq({}, eval('g:ev')) + eq('window', eval('g:amatchpre')) + eq(1, eval('g:cdprecount')) + eq(0, eval('g:cdcount')) local status2, err2 = pcall(function() - command('lcd '..dirs[2] .. '/doesnotexist') + command('lcd '..dirs[2]..'/doesnotexist') end) + eq({directory=dirs[2]..'/doesnotexist', scope='window', changed_window=false}, eval('g:evpre')) eq({}, eval('g:ev')) + eq('window', eval('g:amatchpre')) + eq(2, eval('g:cdprecount')) + eq(0, eval('g:cdcount')) local status3, err3 = pcall(function() - command('lcd '..dirs[3] .. '/doesnotexist') + command('lcd '..dirs[3]..'/doesnotexist') end) + eq({directory=dirs[3]..'/doesnotexist', scope='window', changed_window=false}, eval('g:evpre')) eq({}, eval('g:ev')) + eq('window', eval('g:amatchpre')) + eq(3, eval('g:cdprecount')) + eq(0, eval('g:cdcount')) eq(false, status1) eq(false, status2) @@ -99,85 +124,121 @@ describe('autocmd DirChanged', function() eq('E344:', string.match(err3, "E%d*:")) end) - it("is triggered by 'autochdir'", function() + it("are triggered by 'autochdir'", function() command('set autochdir') command('split '..dirs[1]..'/foo') + eq({directory=dirs[1], scope='window', changed_window=false}, eval('g:evpre')) eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev')) + eq('auto', eval('g:amatchpre')) eq('auto', eval('g:amatch')) + eq(1, eval('g:cdprecount')) + eq(1, eval('g:cdcount')) command('split '..dirs[2]..'/bar') + eq({directory=dirs[2], scope='window', changed_window=false}, eval('g:evpre')) eq({cwd=dirs[2], scope='window', changed_window=false}, eval('g:ev')) eq('auto', eval('g:amatch')) - + eq(2, eval('g:cdprecount')) eq(2, eval('g:cdcount')) end) - it('does not trigger if directory has not changed', function() + it('do not trigger if directory has not changed', function() command('lcd '..dirs[1]) + eq({directory=dirs[1], scope='window', changed_window=false}, eval('g:evpre')) eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev')) + eq('window', eval('g:amatchpre')) eq('window', eval('g:amatch')) + eq(1, eval('g:cdprecount')) eq(1, eval('g:cdcount')) + command('let g:evpre = {}') command('let g:ev = {}') command('lcd '..dirs[1]) + eq({}, eval('g:evpre')) eq({}, eval('g:ev')) + eq(1, eval('g:cdprecount')) eq(1, eval('g:cdcount')) if iswin() then command('lcd '..win_dirs[1]) + eq({}, eval('g:evpre')) eq({}, eval('g:ev')) + eq(1, eval('g:cdprecount')) eq(1, eval('g:cdcount')) end command('tcd '..dirs[2]) + eq({directory=dirs[2], scope='tabpage', changed_window=false}, eval('g:evpre')) eq({cwd=dirs[2], scope='tabpage', changed_window=false}, eval('g:ev')) + eq('tabpage', eval('g:amatchpre')) eq('tabpage', eval('g:amatch')) + eq(2, eval('g:cdprecount')) eq(2, eval('g:cdcount')) + command('let g:evpre = {}') command('let g:ev = {}') command('tcd '..dirs[2]) + eq({}, eval('g:evpre')) eq({}, eval('g:ev')) + eq(2, eval('g:cdprecount')) eq(2, eval('g:cdcount')) if iswin() then command('tcd '..win_dirs[2]) + eq({}, eval('g:evpre')) eq({}, eval('g:ev')) + eq(2, eval('g:cdprecount')) eq(2, eval('g:cdcount')) end command('cd '..dirs[3]) + eq({directory=dirs[3], scope='global', changed_window=false}, eval('g:evpre')) eq({cwd=dirs[3], scope='global', changed_window=false}, eval('g:ev')) eq('global', eval('g:amatch')) + eq(3, eval('g:cdprecount')) eq(3, eval('g:cdcount')) + command('let g:evpre = {}') command('let g:ev = {}') command('cd '..dirs[3]) + eq({}, eval('g:evpre')) eq({}, eval('g:ev')) + eq(3, eval('g:cdprecount')) eq(3, eval('g:cdcount')) if iswin() then command('cd '..win_dirs[3]) + eq({}, eval('g:evpre')) eq({}, eval('g:ev')) + eq(3, eval('g:cdprecount')) eq(3, eval('g:cdcount')) end command('set autochdir') command('split '..dirs[1]..'/foo') + eq({directory=dirs[1], scope='window', changed_window=false}, eval('g:evpre')) eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev')) + eq('auto', eval('g:amatchpre')) eq('auto', eval('g:amatch')) + eq(4, eval('g:cdprecount')) eq(4, eval('g:cdcount')) + command('let g:evpre = {}') command('let g:ev = {}') command('split '..dirs[1]..'/bar') + eq({}, eval('g:evpre')) eq({}, eval('g:ev')) + eq(4, eval('g:cdprecount')) eq(4, eval('g:cdcount')) if iswin() then command('split '..win_dirs[1]..'/baz') + eq({}, eval('g:evpre')) eq({}, eval('g:ev')) + eq(4, eval('g:cdprecount')) eq(4, eval('g:cdcount')) end end) - it("is triggered by switching to win/tab with different CWD #6054", function() + it("are triggered by switching to win/tab with different CWD #6054", function() command('lcd '..dirs[3]) -- window 3 command('split '..dirs[2]..'/foo') -- window 2 command('lcd '..dirs[2]) @@ -185,72 +246,105 @@ describe('autocmd DirChanged', function() command('lcd '..dirs[1]) command('2wincmd w') -- window 2 + eq({directory=dirs[2], scope='window', changed_window=true}, eval('g:evpre')) eq({cwd=dirs[2], scope='window', changed_window=true}, eval('g:ev')) + eq('window', eval('g:amatchpre')) eq('window', eval('g:amatch')) + eq(4, eval('g:cdprecount')) eq(4, eval('g:cdcount')) command('tabnew') -- tab 2 (tab-local CWD) + eq(4, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(4, eval('g:cdcount')) -- same CWD, no DirChanged event command('tcd '..dirs[3]) command('tabnext') -- tab 1 (no tab-local CWD) + eq({directory=dirs[2], scope='window', changed_window=true}, eval('g:evpre')) eq({cwd=dirs[2], scope='window', changed_window=true}, eval('g:ev')) + eq('window', eval('g:amatchpre')) eq('window', eval('g:amatch')) command('tabnext') -- tab 2 + eq({directory=dirs[3], scope='tabpage', changed_window=true}, eval('g:evpre')) eq({cwd=dirs[3], scope='tabpage', changed_window=true}, eval('g:ev')) + eq('tabpage', eval('g:amatchpre')) eq('tabpage', eval('g:amatch')) + eq(7, eval('g:cdprecount')) eq(7, eval('g:cdcount')) command('tabnext') -- tab 1 command('3wincmd w') -- window 3 + eq(9, eval('g:cdprecount')) eq(9, eval('g:cdcount')) command('tabnext') -- tab 2 (has the *same* CWD) + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event if iswin() then command('tabnew') -- tab 3 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event command('tcd '..win_dirs[3]) + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event command('tabnext') -- tab 1 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event command('tabprevious') -- tab 3 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event command('tabprevious') -- tab 2 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event command('tabprevious') -- tab 1 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event command('lcd '..win_dirs[3]) -- window 3 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event command('tabnext') -- tab 2 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event command('tabnext') -- tab 3 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event command('tabnext') -- tab 1 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event command('tabprevious') -- tab 3 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event end end) - it('is triggered by nvim_set_current_dir()', function() + it('are triggered by nvim_set_current_dir()', function() request('nvim_set_current_dir', dirs[1]) + eq({directory=dirs[1], scope='global', changed_window=false}, eval('g:evpre')) eq({cwd=dirs[1], scope='global', changed_window=false}, eval('g:ev')) + eq(1, eval('g:cdprecount')) + eq(1, eval('g:cdcount')) request('nvim_set_current_dir', dirs[2]) + eq({directory=dirs[2], scope='global', changed_window=false}, eval('g:evpre')) eq({cwd=dirs[2], scope='global', changed_window=false}, eval('g:ev')) + eq(2, eval('g:cdprecount')) + eq(2, eval('g:cdcount')) local status, err = pcall(function() request('nvim_set_current_dir', '/doesnotexist') end) eq(false, status) eq('Failed to change directory', string.match(err, ': (.*)')) - eq({cwd=dirs[2], scope='global', changed_window=false}, eval('g:ev')) + eq({directory='/doesnotexist', scope='global', changed_window=false}, eval('g:evpre')) + eq(3, eval('g:cdprecount')) + eq(2, eval('g:cdcount')) end) - it('works when local to buffer', function() + it('work when local to buffer', function() + command('let g:triggeredpre = 0') command('let g:triggered = 0') + command('autocmd DirChangedPre <buffer> let g:triggeredpre = 1') command('autocmd DirChanged <buffer> let g:triggered = 1') command('cd '..dirs[1]) + eq(1, eval('g:triggeredpre')) eq(1, eval('g:triggered')) end) end) |