mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
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)
28e8f73ae2
This commit is contained in:
parent
851252f79d
commit
059d36e326
@ -525,8 +525,19 @@ DirChanged After the |current-directory| was changed.
|
|||||||
"global" to trigger on `:cd`
|
"global" to trigger on `:cd`
|
||||||
"auto" to trigger on 'autochdir'.
|
"auto" to trigger on 'autochdir'.
|
||||||
Sets these |v:event| keys:
|
Sets these |v:event| keys:
|
||||||
cwd: current working directory
|
cwd: current working directory
|
||||||
scope: "global", "tabpage", "window"
|
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
|
changed_window: v:true if we fired the event
|
||||||
switching window (or tab)
|
switching window (or tab)
|
||||||
<afile> is set to the new directory name.
|
<afile> is set to the new directory name.
|
||||||
|
@ -433,7 +433,8 @@ Vimscript compatibility:
|
|||||||
`this_session` does not alias to |v:this_session|
|
`this_session` does not alias to |v:this_session|
|
||||||
|
|
||||||
Working directory (Vim implemented some of these later than Nvim):
|
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
|
- |getcwd()| and |haslocaldir()| may throw errors if the tab page or window
|
||||||
cannot be found. *E5000* *E5001* *E5002*
|
cannot be found. *E5000* *E5001* *E5002*
|
||||||
- |haslocaldir()| checks for tab-local directory if and only if -1 is passed as
|
- |haslocaldir()| checks for tab-local directory if and only if -1 is passed as
|
||||||
|
@ -40,6 +40,7 @@ return {
|
|||||||
'DiagnosticChanged', -- diagnostics in a buffer were modified
|
'DiagnosticChanged', -- diagnostics in a buffer were modified
|
||||||
'DiffUpdated', -- diffs have been updated
|
'DiffUpdated', -- diffs have been updated
|
||||||
'DirChanged', -- directory changed
|
'DirChanged', -- directory changed
|
||||||
|
'DirChangedPre', -- directory is going to change
|
||||||
'EncodingChanged', -- after changing the 'encoding' option
|
'EncodingChanged', -- after changing the 'encoding' option
|
||||||
'ExitPre', -- before exiting
|
'ExitPre', -- before exiting
|
||||||
'FileAppendCmd', -- append to a file using command
|
'FileAppendCmd', -- append to a file using command
|
||||||
@ -132,18 +133,14 @@ return {
|
|||||||
nvim_specific = {
|
nvim_specific = {
|
||||||
BufModifiedSet=true,
|
BufModifiedSet=true,
|
||||||
DiagnosticChanged=true,
|
DiagnosticChanged=true,
|
||||||
DirChanged=true,
|
|
||||||
RecordingEnter=true,
|
RecordingEnter=true,
|
||||||
RecordingLeave=true,
|
RecordingLeave=true,
|
||||||
Signal=true,
|
Signal=true,
|
||||||
TabClosed=true,
|
|
||||||
TabNew=true,
|
|
||||||
TabNewEntered=true,
|
TabNewEntered=true,
|
||||||
TermClose=true,
|
TermClose=true,
|
||||||
TermOpen=true,
|
TermOpen=true,
|
||||||
UIEnter=true,
|
UIEnter=true,
|
||||||
UILeave=true,
|
UILeave=true,
|
||||||
WinClosed=true,
|
|
||||||
WinScrolled=true,
|
WinScrolled=true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -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_CMDLINELEAVE || event == EVENT_CMDWINENTER
|
||||||
|| event == EVENT_CMDWINLEAVE || event == EVENT_CMDUNDEFINED
|
|| event == EVENT_CMDWINLEAVE || event == EVENT_CMDUNDEFINED
|
||||||
|| event == EVENT_COLORSCHEME || event == EVENT_COLORSCHEMEPRE
|
|| event == EVENT_COLORSCHEME || event == EVENT_COLORSCHEMEPRE
|
||||||
|| event == EVENT_DIRCHANGED || event == EVENT_FILETYPE
|
|| event == EVENT_DIRCHANGED || event == EVENT_DIRCHANGEDPRE
|
||||||
|| event == EVENT_FUNCUNDEFINED || event == EVENT_MODECHANGED
|
|| event == EVENT_FILETYPE || event == EVENT_FUNCUNDEFINED
|
||||||
|| event == EVENT_OPTIONSET || event == EVENT_QUICKFIXCMDPOST
|
|| event == EVENT_MODECHANGED || event == EVENT_OPTIONSET
|
||||||
|| event == EVENT_QUICKFIXCMDPRE || event == EVENT_REMOTEREPLY
|
|| event == EVENT_QUICKFIXCMDPOST || event == EVENT_QUICKFIXCMDPRE
|
||||||
|| event == EVENT_SPELLFILEMISSING || event == EVENT_SYNTAX
|
|| event == EVENT_REMOTEREPLY || event == EVENT_SPELLFILEMISSING
|
||||||
|| event == EVENT_SIGNAL || event == EVENT_TABCLOSED
|
|| event == EVENT_SYNTAX || event == EVENT_SIGNAL
|
||||||
|| event == EVENT_WINCLOSED) {
|
|| event == EVENT_TABCLOSED || event == EVENT_WINCLOSED) {
|
||||||
fname = vim_strsave(fname);
|
fname = vim_strsave(fname);
|
||||||
} else {
|
} else {
|
||||||
fname = (char_u *)FullName_save((char *)fname, false);
|
fname = (char_u *)FullName_save((char *)fname, false);
|
||||||
|
@ -7784,7 +7784,7 @@ static char_u *get_prevdir(CdScope scope)
|
|||||||
/// Deal with the side effects of changing the current directory.
|
/// Deal with the side effects of changing the current directory.
|
||||||
///
|
///
|
||||||
/// @param scope Scope of the function call (global, tab or window).
|
/// @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.
|
// Always overwrite the window-local CWD.
|
||||||
XFREE_CLEAR(curwin->w_localdir);
|
XFREE_CLEAR(curwin->w_localdir);
|
||||||
@ -7825,7 +7825,7 @@ void post_chdir(CdScope scope, bool trigger_dirchanged)
|
|||||||
shorten_fnames(true);
|
shorten_fnames(true);
|
||||||
|
|
||||||
if (trigger_dirchanged) {
|
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;
|
bool dir_differs = pdir == NULL || pathcmp((char *)pdir, (char *)new_dir, -1) != 0;
|
||||||
if (dir_differs && vim_chdir(new_dir) != 0) {
|
if (dir_differs) {
|
||||||
emsg(_(e_failed));
|
do_autocmd_dirchanged((char *)new_dir, scope, kCdCauseManual, true);
|
||||||
xfree(pdir);
|
if (vim_chdir(new_dir) != 0) {
|
||||||
return false;
|
emsg(_(e_failed));
|
||||||
|
xfree(pdir);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char_u **pp;
|
char_u **pp;
|
||||||
|
@ -1600,11 +1600,13 @@ theend:
|
|||||||
return file_name;
|
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;
|
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
|
// No autocommand was defined or we changed
|
||||||
// the directory from this autocommand.
|
// the directory from this autocommand.
|
||||||
return;
|
return;
|
||||||
@ -1638,8 +1640,12 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, CdCause cause)
|
|||||||
new_dir = new_dir_buf;
|
new_dir = new_dir_buf;
|
||||||
#endif
|
#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("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_add_bool(dict, S_LEN("changed_window"), cause == kCdCauseWindow);
|
||||||
tv_dict_set_keys_readonly(dict);
|
tv_dict_set_keys_readonly(dict);
|
||||||
|
|
||||||
@ -1655,8 +1661,7 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, CdCause cause)
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, (char_u *)new_dir, false,
|
apply_autocmds(event, (char_u *)buf, (char_u *)new_dir, false, curbuf);
|
||||||
curbuf);
|
|
||||||
|
|
||||||
restore_v_event(dict, &save_v_event);
|
restore_v_event(dict, &save_v_event);
|
||||||
|
|
||||||
@ -1682,12 +1687,16 @@ int vim_chdirfile(char_u *fname, CdCause cause)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cause != kCdCauseOther) {
|
||||||
|
do_autocmd_dirchanged(dir, kCdScopeWindow, cause, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (os_chdir(dir) != 0) {
|
if (os_chdir(dir) != 0) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause != kCdCauseOther) {
|
if (cause != kCdCauseOther) {
|
||||||
do_autocmd_dirchanged(dir, kCdScopeWindow, cause);
|
do_autocmd_dirchanged(dir, kCdScopeWindow, cause, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
@ -1850,14 +1850,16 @@ endfunc
|
|||||||
|
|
||||||
function Test_dirchanged_global()
|
function Test_dirchanged_global()
|
||||||
call s:Before_test_dirchanged()
|
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, "cd:")
|
||||||
autocmd test_dirchanged DirChanged global call add(s:li, expand("<afile>"))
|
autocmd test_dirchanged DirChanged global call add(s:li, expand("<afile>"))
|
||||||
call chdir(s:dir_foo)
|
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 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)
|
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()
|
call s:After_test_dirchanged()
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
@ -1879,6 +1881,7 @@ function Test_dirchanged_auto()
|
|||||||
CheckOption autochdir
|
CheckOption autochdir
|
||||||
call s:Before_test_dirchanged()
|
call s:Before_test_dirchanged()
|
||||||
call test_autochdir()
|
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, "auto:")
|
||||||
autocmd test_dirchanged DirChanged auto call add(s:li, expand("<afile>"))
|
autocmd test_dirchanged DirChanged auto call add(s:li, expand("<afile>"))
|
||||||
set acd
|
set acd
|
||||||
@ -1886,7 +1889,8 @@ function Test_dirchanged_auto()
|
|||||||
call assert_equal([], s:li)
|
call assert_equal([], s:li)
|
||||||
exe 'edit ' . s:dir_foo . '/Xfile'
|
exe 'edit ' . s:dir_foo . '/Xfile'
|
||||||
call assert_equal(s:dir_foo, getcwd())
|
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
|
set noacd
|
||||||
bwipe!
|
bwipe!
|
||||||
call s:After_test_dirchanged()
|
call s:After_test_dirchanged()
|
||||||
|
@ -4645,20 +4645,29 @@ void fix_current_dir(void)
|
|||||||
globaldir = (char_u *)xstrdup(cwd);
|
globaldir = (char_u *)xstrdup(cwd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (os_chdir(new_dir) == 0) {
|
bool dir_differs = pathcmp(new_dir, cwd, -1) != 0;
|
||||||
if (!p_acd && pathcmp(new_dir, cwd, -1) != 0) {
|
if (!p_acd && dir_differs) {
|
||||||
do_autocmd_dirchanged(new_dir, curwin->w_localdir
|
do_autocmd_dirchanged(new_dir, curwin->w_localdir ? kCdScopeWindow : kCdScopeTabpage,
|
||||||
? kCdScopeWindow : kCdScopeTabpage, kCdCauseWindow);
|
kCdCauseWindow, true);
|
||||||
}
|
|
||||||
last_chdir_reason = NULL;
|
|
||||||
shorten_fnames(true);
|
|
||||||
}
|
}
|
||||||
|
if (os_chdir(new_dir) == 0) {
|
||||||
|
if (!p_acd && dir_differs) {
|
||||||
|
do_autocmd_dirchanged(new_dir, curwin->w_localdir ? kCdScopeWindow : kCdScopeTabpage,
|
||||||
|
kCdCauseWindow, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last_chdir_reason = NULL;
|
||||||
|
shorten_fnames(true);
|
||||||
} else if (globaldir != NULL) {
|
} else if (globaldir != NULL) {
|
||||||
// Window doesn't have a local directory and we are not in the global
|
// Window doesn't have a local directory and we are not in the global
|
||||||
// directory: Change to the global directory.
|
// 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 (os_chdir((char *)globaldir) == 0) {
|
||||||
if (!p_acd && pathcmp((char *)globaldir, cwd, -1) != 0) {
|
if (!p_acd && dir_differs) {
|
||||||
do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, kCdCauseWindow);
|
do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, kCdCauseWindow, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XFREE_CLEAR(globaldir);
|
XFREE_CLEAR(globaldir);
|
||||||
|
@ -8,7 +8,7 @@ local eval = h.eval
|
|||||||
local request = h.request
|
local request = h.request
|
||||||
local iswin = h.iswin
|
local iswin = h.iswin
|
||||||
|
|
||||||
describe('autocmd DirChanged', function()
|
describe('autocmd DirChanged and DirChangedPre', function()
|
||||||
local curdir = string.gsub(lfs.currentdir(), '\\', '/')
|
local curdir = string.gsub(lfs.currentdir(), '\\', '/')
|
||||||
local dirs = {
|
local dirs = {
|
||||||
curdir .. '/Xtest-functional-autocmd-dirchanged.dir1',
|
curdir .. '/Xtest-functional-autocmd-dirchanged.dir1',
|
||||||
@ -26,31 +26,43 @@ describe('autocmd DirChanged', function()
|
|||||||
|
|
||||||
before_each(function()
|
before_each(function()
|
||||||
clear()
|
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] '
|
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.
|
-- 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: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)
|
end)
|
||||||
|
|
||||||
it('sets v:event and <amatch>', function()
|
it('set v:event and <amatch>', function()
|
||||||
command('lcd '..dirs[1])
|
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({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev'))
|
||||||
|
eq('window', eval('g:amatchpre'))
|
||||||
eq('window', eval('g:amatch'))
|
eq('window', eval('g:amatch'))
|
||||||
|
eq(1, eval('g:cdprecount'))
|
||||||
eq(1, eval('g:cdcount'))
|
eq(1, eval('g:cdcount'))
|
||||||
|
|
||||||
command('tcd '..dirs[2])
|
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({cwd=dirs[2], scope='tabpage', changed_window=false}, eval('g:ev'))
|
||||||
|
eq('tabpage', eval('g:amatchpre'))
|
||||||
eq('tabpage', eval('g:amatch'))
|
eq('tabpage', eval('g:amatch'))
|
||||||
|
eq(2, eval('g:cdprecount'))
|
||||||
eq(2, eval('g:cdcount'))
|
eq(2, eval('g:cdcount'))
|
||||||
|
|
||||||
command('cd '..dirs[3])
|
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({cwd=dirs[3], scope='global', changed_window=false}, eval('g:ev'))
|
||||||
|
eq('global', eval('g:amatchpre'))
|
||||||
eq('global', eval('g:amatch'))
|
eq('global', eval('g:amatch'))
|
||||||
|
eq(3, eval('g:cdprecount'))
|
||||||
eq(3, eval('g:cdcount'))
|
eq(3, eval('g:cdcount'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('sets getcwd() during event #6260', function()
|
it('DirChanged set getcwd() during event #6260', function()
|
||||||
command('lcd '..dirs[1])
|
command('lcd '..dirs[1])
|
||||||
eq(dirs[1], eval('g:getcwd'))
|
eq(dirs[1], eval('g:getcwd'))
|
||||||
|
|
||||||
@ -61,7 +73,7 @@ describe('autocmd DirChanged', function()
|
|||||||
eq(dirs[3], eval('g:getcwd'))
|
eq(dirs[3], eval('g:getcwd'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('disallows recursion', function()
|
it('disallow recursion', function()
|
||||||
command('set shellslash')
|
command('set shellslash')
|
||||||
-- Set up a _nested_ handler.
|
-- Set up a _nested_ handler.
|
||||||
command('autocmd DirChanged * nested lcd '..dirs[3])
|
command('autocmd DirChanged * nested lcd '..dirs[3])
|
||||||
@ -72,23 +84,36 @@ describe('autocmd DirChanged', function()
|
|||||||
eq(dirs[3], eval('getcwd()'))
|
eq(dirs[3], eval('getcwd()'))
|
||||||
end)
|
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:ev = {}')
|
||||||
|
command('let g:cdcount = 0')
|
||||||
|
|
||||||
local status1, err1 = pcall(function()
|
local status1, err1 = pcall(function()
|
||||||
command('lcd '..dirs[1] .. '/doesnotexist')
|
command('lcd '..dirs[1]..'/doesnotexist')
|
||||||
end)
|
end)
|
||||||
|
eq({directory=dirs[1]..'/doesnotexist', scope='window', changed_window=false}, eval('g:evpre'))
|
||||||
eq({}, eval('g:ev'))
|
eq({}, eval('g:ev'))
|
||||||
|
eq('window', eval('g:amatchpre'))
|
||||||
|
eq(1, eval('g:cdprecount'))
|
||||||
|
eq(0, eval('g:cdcount'))
|
||||||
|
|
||||||
local status2, err2 = pcall(function()
|
local status2, err2 = pcall(function()
|
||||||
command('lcd '..dirs[2] .. '/doesnotexist')
|
command('lcd '..dirs[2]..'/doesnotexist')
|
||||||
end)
|
end)
|
||||||
|
eq({directory=dirs[2]..'/doesnotexist', scope='window', changed_window=false}, eval('g:evpre'))
|
||||||
eq({}, eval('g:ev'))
|
eq({}, eval('g:ev'))
|
||||||
|
eq('window', eval('g:amatchpre'))
|
||||||
|
eq(2, eval('g:cdprecount'))
|
||||||
|
eq(0, eval('g:cdcount'))
|
||||||
|
|
||||||
local status3, err3 = pcall(function()
|
local status3, err3 = pcall(function()
|
||||||
command('lcd '..dirs[3] .. '/doesnotexist')
|
command('lcd '..dirs[3]..'/doesnotexist')
|
||||||
end)
|
end)
|
||||||
|
eq({directory=dirs[3]..'/doesnotexist', scope='window', changed_window=false}, eval('g:evpre'))
|
||||||
eq({}, eval('g:ev'))
|
eq({}, eval('g:ev'))
|
||||||
|
eq('window', eval('g:amatchpre'))
|
||||||
|
eq(3, eval('g:cdprecount'))
|
||||||
|
eq(0, eval('g:cdcount'))
|
||||||
|
|
||||||
eq(false, status1)
|
eq(false, status1)
|
||||||
eq(false, status2)
|
eq(false, status2)
|
||||||
@ -99,85 +124,121 @@ describe('autocmd DirChanged', function()
|
|||||||
eq('E344:', string.match(err3, "E%d*:"))
|
eq('E344:', string.match(err3, "E%d*:"))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("is triggered by 'autochdir'", function()
|
it("are triggered by 'autochdir'", function()
|
||||||
command('set autochdir')
|
command('set autochdir')
|
||||||
|
|
||||||
command('split '..dirs[1]..'/foo')
|
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({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev'))
|
||||||
|
eq('auto', eval('g:amatchpre'))
|
||||||
eq('auto', eval('g:amatch'))
|
eq('auto', eval('g:amatch'))
|
||||||
|
eq(1, eval('g:cdprecount'))
|
||||||
|
eq(1, eval('g:cdcount'))
|
||||||
|
|
||||||
command('split '..dirs[2]..'/bar')
|
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({cwd=dirs[2], scope='window', changed_window=false}, eval('g:ev'))
|
||||||
eq('auto', eval('g:amatch'))
|
eq('auto', eval('g:amatch'))
|
||||||
|
eq(2, eval('g:cdprecount'))
|
||||||
eq(2, eval('g:cdcount'))
|
eq(2, eval('g:cdcount'))
|
||||||
end)
|
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])
|
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({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev'))
|
||||||
|
eq('window', eval('g:amatchpre'))
|
||||||
eq('window', eval('g:amatch'))
|
eq('window', eval('g:amatch'))
|
||||||
|
eq(1, eval('g:cdprecount'))
|
||||||
eq(1, eval('g:cdcount'))
|
eq(1, eval('g:cdcount'))
|
||||||
|
command('let g:evpre = {}')
|
||||||
command('let g:ev = {}')
|
command('let g:ev = {}')
|
||||||
command('lcd '..dirs[1])
|
command('lcd '..dirs[1])
|
||||||
|
eq({}, eval('g:evpre'))
|
||||||
eq({}, eval('g:ev'))
|
eq({}, eval('g:ev'))
|
||||||
|
eq(1, eval('g:cdprecount'))
|
||||||
eq(1, eval('g:cdcount'))
|
eq(1, eval('g:cdcount'))
|
||||||
|
|
||||||
if iswin() then
|
if iswin() then
|
||||||
command('lcd '..win_dirs[1])
|
command('lcd '..win_dirs[1])
|
||||||
|
eq({}, eval('g:evpre'))
|
||||||
eq({}, eval('g:ev'))
|
eq({}, eval('g:ev'))
|
||||||
|
eq(1, eval('g:cdprecount'))
|
||||||
eq(1, eval('g:cdcount'))
|
eq(1, eval('g:cdcount'))
|
||||||
end
|
end
|
||||||
|
|
||||||
command('tcd '..dirs[2])
|
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({cwd=dirs[2], scope='tabpage', changed_window=false}, eval('g:ev'))
|
||||||
|
eq('tabpage', eval('g:amatchpre'))
|
||||||
eq('tabpage', eval('g:amatch'))
|
eq('tabpage', eval('g:amatch'))
|
||||||
|
eq(2, eval('g:cdprecount'))
|
||||||
eq(2, eval('g:cdcount'))
|
eq(2, eval('g:cdcount'))
|
||||||
|
command('let g:evpre = {}')
|
||||||
command('let g:ev = {}')
|
command('let g:ev = {}')
|
||||||
command('tcd '..dirs[2])
|
command('tcd '..dirs[2])
|
||||||
|
eq({}, eval('g:evpre'))
|
||||||
eq({}, eval('g:ev'))
|
eq({}, eval('g:ev'))
|
||||||
|
eq(2, eval('g:cdprecount'))
|
||||||
eq(2, eval('g:cdcount'))
|
eq(2, eval('g:cdcount'))
|
||||||
|
|
||||||
if iswin() then
|
if iswin() then
|
||||||
command('tcd '..win_dirs[2])
|
command('tcd '..win_dirs[2])
|
||||||
|
eq({}, eval('g:evpre'))
|
||||||
eq({}, eval('g:ev'))
|
eq({}, eval('g:ev'))
|
||||||
|
eq(2, eval('g:cdprecount'))
|
||||||
eq(2, eval('g:cdcount'))
|
eq(2, eval('g:cdcount'))
|
||||||
end
|
end
|
||||||
|
|
||||||
command('cd '..dirs[3])
|
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({cwd=dirs[3], scope='global', changed_window=false}, eval('g:ev'))
|
||||||
eq('global', eval('g:amatch'))
|
eq('global', eval('g:amatch'))
|
||||||
|
eq(3, eval('g:cdprecount'))
|
||||||
eq(3, eval('g:cdcount'))
|
eq(3, eval('g:cdcount'))
|
||||||
|
command('let g:evpre = {}')
|
||||||
command('let g:ev = {}')
|
command('let g:ev = {}')
|
||||||
command('cd '..dirs[3])
|
command('cd '..dirs[3])
|
||||||
|
eq({}, eval('g:evpre'))
|
||||||
eq({}, eval('g:ev'))
|
eq({}, eval('g:ev'))
|
||||||
|
eq(3, eval('g:cdprecount'))
|
||||||
eq(3, eval('g:cdcount'))
|
eq(3, eval('g:cdcount'))
|
||||||
|
|
||||||
if iswin() then
|
if iswin() then
|
||||||
command('cd '..win_dirs[3])
|
command('cd '..win_dirs[3])
|
||||||
|
eq({}, eval('g:evpre'))
|
||||||
eq({}, eval('g:ev'))
|
eq({}, eval('g:ev'))
|
||||||
|
eq(3, eval('g:cdprecount'))
|
||||||
eq(3, eval('g:cdcount'))
|
eq(3, eval('g:cdcount'))
|
||||||
end
|
end
|
||||||
|
|
||||||
command('set autochdir')
|
command('set autochdir')
|
||||||
|
|
||||||
command('split '..dirs[1]..'/foo')
|
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({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev'))
|
||||||
|
eq('auto', eval('g:amatchpre'))
|
||||||
eq('auto', eval('g:amatch'))
|
eq('auto', eval('g:amatch'))
|
||||||
|
eq(4, eval('g:cdprecount'))
|
||||||
eq(4, eval('g:cdcount'))
|
eq(4, eval('g:cdcount'))
|
||||||
|
command('let g:evpre = {}')
|
||||||
command('let g:ev = {}')
|
command('let g:ev = {}')
|
||||||
command('split '..dirs[1]..'/bar')
|
command('split '..dirs[1]..'/bar')
|
||||||
|
eq({}, eval('g:evpre'))
|
||||||
eq({}, eval('g:ev'))
|
eq({}, eval('g:ev'))
|
||||||
|
eq(4, eval('g:cdprecount'))
|
||||||
eq(4, eval('g:cdcount'))
|
eq(4, eval('g:cdcount'))
|
||||||
|
|
||||||
if iswin() then
|
if iswin() then
|
||||||
command('split '..win_dirs[1]..'/baz')
|
command('split '..win_dirs[1]..'/baz')
|
||||||
|
eq({}, eval('g:evpre'))
|
||||||
eq({}, eval('g:ev'))
|
eq({}, eval('g:ev'))
|
||||||
|
eq(4, eval('g:cdprecount'))
|
||||||
eq(4, eval('g:cdcount'))
|
eq(4, eval('g:cdcount'))
|
||||||
end
|
end
|
||||||
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('lcd '..dirs[3]) -- window 3
|
||||||
command('split '..dirs[2]..'/foo') -- window 2
|
command('split '..dirs[2]..'/foo') -- window 2
|
||||||
command('lcd '..dirs[2])
|
command('lcd '..dirs[2])
|
||||||
@ -185,72 +246,105 @@ describe('autocmd DirChanged', function()
|
|||||||
command('lcd '..dirs[1])
|
command('lcd '..dirs[1])
|
||||||
|
|
||||||
command('2wincmd w') -- window 2
|
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({cwd=dirs[2], scope='window', changed_window=true}, eval('g:ev'))
|
||||||
|
eq('window', eval('g:amatchpre'))
|
||||||
eq('window', eval('g:amatch'))
|
eq('window', eval('g:amatch'))
|
||||||
|
|
||||||
|
eq(4, eval('g:cdprecount'))
|
||||||
eq(4, eval('g:cdcount'))
|
eq(4, eval('g:cdcount'))
|
||||||
command('tabnew') -- tab 2 (tab-local CWD)
|
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
|
eq(4, eval('g:cdcount')) -- same CWD, no DirChanged event
|
||||||
command('tcd '..dirs[3])
|
command('tcd '..dirs[3])
|
||||||
command('tabnext') -- tab 1 (no tab-local CWD)
|
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({cwd=dirs[2], scope='window', changed_window=true}, eval('g:ev'))
|
||||||
|
eq('window', eval('g:amatchpre'))
|
||||||
eq('window', eval('g:amatch'))
|
eq('window', eval('g:amatch'))
|
||||||
command('tabnext') -- tab 2
|
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({cwd=dirs[3], scope='tabpage', changed_window=true}, eval('g:ev'))
|
||||||
|
eq('tabpage', eval('g:amatchpre'))
|
||||||
eq('tabpage', eval('g:amatch'))
|
eq('tabpage', eval('g:amatch'))
|
||||||
|
eq(7, eval('g:cdprecount'))
|
||||||
eq(7, eval('g:cdcount'))
|
eq(7, eval('g:cdcount'))
|
||||||
|
|
||||||
command('tabnext') -- tab 1
|
command('tabnext') -- tab 1
|
||||||
command('3wincmd w') -- window 3
|
command('3wincmd w') -- window 3
|
||||||
|
eq(9, eval('g:cdprecount'))
|
||||||
eq(9, eval('g:cdcount'))
|
eq(9, eval('g:cdcount'))
|
||||||
command('tabnext') -- tab 2 (has the *same* CWD)
|
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
|
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
||||||
|
|
||||||
if iswin() then
|
if iswin() then
|
||||||
command('tabnew') -- tab 3
|
command('tabnew') -- tab 3
|
||||||
|
eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event
|
||||||
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
||||||
command('tcd '..win_dirs[3])
|
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
|
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
||||||
command('tabnext') -- tab 1
|
command('tabnext') -- tab 1
|
||||||
|
eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event
|
||||||
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
||||||
command('tabprevious') -- tab 3
|
command('tabprevious') -- tab 3
|
||||||
|
eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event
|
||||||
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
||||||
command('tabprevious') -- tab 2
|
command('tabprevious') -- tab 2
|
||||||
|
eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event
|
||||||
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
||||||
command('tabprevious') -- tab 1
|
command('tabprevious') -- tab 1
|
||||||
|
eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event
|
||||||
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
||||||
command('lcd '..win_dirs[3]) -- window 3
|
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
|
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
||||||
command('tabnext') -- tab 2
|
command('tabnext') -- tab 2
|
||||||
|
eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event
|
||||||
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
||||||
command('tabnext') -- tab 3
|
command('tabnext') -- tab 3
|
||||||
|
eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event
|
||||||
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
||||||
command('tabnext') -- tab 1
|
command('tabnext') -- tab 1
|
||||||
|
eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event
|
||||||
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
||||||
command('tabprevious') -- tab 3
|
command('tabprevious') -- tab 3
|
||||||
|
eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event
|
||||||
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
|
||||||
end
|
end
|
||||||
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])
|
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({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])
|
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({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()
|
local status, err = pcall(function()
|
||||||
request('nvim_set_current_dir', '/doesnotexist')
|
request('nvim_set_current_dir', '/doesnotexist')
|
||||||
end)
|
end)
|
||||||
eq(false, status)
|
eq(false, status)
|
||||||
eq('Failed to change directory', string.match(err, ': (.*)'))
|
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)
|
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('let g:triggered = 0')
|
||||||
|
command('autocmd DirChangedPre <buffer> let g:triggeredpre = 1')
|
||||||
command('autocmd DirChanged <buffer> let g:triggered = 1')
|
command('autocmd DirChanged <buffer> let g:triggered = 1')
|
||||||
command('cd '..dirs[1])
|
command('cd '..dirs[1])
|
||||||
|
eq(1, eval('g:triggeredpre'))
|
||||||
eq(1, eval('g:triggered'))
|
eq(1, eval('g:triggered'))
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user