mirror of
https://github.com/neovim/neovim.git
synced 2025-09-29 22:48:34 +00:00
Merge pull request #17363 from zeertzjq/dirchangedpre
feat(events): add DirChangedPre
This commit is contained in:
@@ -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,
|
||||
},
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -7797,7 +7797,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);
|
||||
@@ -7838,7 +7838,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7882,10 +7882,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;
|
||||
|
@@ -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;
|
||||
|
@@ -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()
|
||||
|
@@ -4688,20 +4688,29 @@ void fix_current_dir(void)
|
||||
globaldir = (char_u *)xstrdup(cwd);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
last_chdir_reason = NULL;
|
||||
shorten_fnames(true);
|
||||
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 && 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) {
|
||||
// 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);
|
||||
|
Reference in New Issue
Block a user