summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-02-09 12:58:20 +0000
committerBram Moolenaar <Bram@vim.org>2022-02-09 12:58:20 +0000
commit28e8f73ae2d90009fd62cd60f97c2643ba44de68 (patch)
treedd381874612b06d380a05c01c6c4b510c861d885 /src
parent68cc2b8a37197872e737fb61244069e13b7227a2 (diff)
patch 8.2.4335: no autocommand event triggered before changing directoryv8.2.4335
Problem: No autocommand event triggered before changing directory. (Ronnie Magatti) Solution: Add DirChangedPre. (closes #9721)
Diffstat (limited to 'src')
-rw-r--r--src/autocmd.c1
-rw-r--r--src/ex_docmd.c54
-rw-r--r--src/misc2.c3
-rw-r--r--src/proto/ex_docmd.pro1
-rw-r--r--src/testdir/test_autocmd.vim12
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h1
7 files changed, 54 insertions, 20 deletions
diff --git a/src/autocmd.c b/src/autocmd.c
index a10be9b928..97b27effd1 100644
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -119,6 +119,7 @@ static struct event_name
{"CursorMovedI", EVENT_CURSORMOVEDI},
{"DiffUpdated", EVENT_DIFFUPDATED},
{"DirChanged", EVENT_DIRCHANGED},
+ {"DirChangedPre", EVENT_DIRCHANGEDPRE},
{"EncodingChanged", EVENT_ENCODINGCHANGED},
{"ExitPre", EVENT_EXITPRE},
{"FileEncoding", EVENT_ENCODINGCHANGED},
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index d8adf85bcb..4003605537 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -7343,6 +7343,26 @@ post_chdir(cdscope_T scope)
}
/*
+ * Trigger DirChangedPre for "acmd_fname" with directory "new_dir".
+ */
+ void
+trigger_DirChangedPre(char_u *acmd_fname, char_u *new_dir)
+{
+#ifdef FEAT_EVAL
+ dict_T *v_event;
+ save_v_event_T save_v_event;
+
+ v_event = get_v_event(&save_v_event);
+ (void)dict_add_string(v_event, "directory", new_dir);
+ dict_set_items_ro(v_event);
+#endif
+ apply_autocmds(EVENT_DIRCHANGEDPRE, acmd_fname, new_dir, FALSE, curbuf);
+#ifdef FEAT_EVAL
+ restore_v_event(v_event, &save_v_event);
+#endif
+}
+
+/*
* Change directory function used by :cd/:tcd/:lcd Ex commands and the
* chdir() function.
* scope == CDSCOPE_WINDOW: changes the window-local directory
@@ -7358,7 +7378,7 @@ changedir_func(
{
char_u *pdir = NULL;
int dir_differs;
- char_u *acmd_fname;
+ char_u *acmd_fname = NULL;
char_u **pp;
if (new_dir == NULL || allbuf_locked())
@@ -7411,12 +7431,23 @@ changedir_func(
new_dir = NameBuff;
}
dir_differs = pdir == NULL
- || pathcmp((char *)pdir, (char *)new_dir, -1) != 0;
- if (dir_differs && vim_chdir(new_dir))
+ || pathcmp((char *)pdir, (char *)new_dir, -1) != 0;
+ if (dir_differs)
{
- emsg(_(e_command_failed));
- vim_free(pdir);
- return FALSE;
+ if (scope == CDSCOPE_WINDOW)
+ acmd_fname = (char_u *)"window";
+ else if (scope == CDSCOPE_TABPAGE)
+ acmd_fname = (char_u *)"tabpage";
+ else
+ acmd_fname = (char_u *)"global";
+ trigger_DirChangedPre(acmd_fname, new_dir);
+
+ if (vim_chdir(new_dir))
+ {
+ emsg(_(e_command_failed));
+ vim_free(pdir);
+ return FALSE;
+ }
}
if (scope == CDSCOPE_WINDOW)
@@ -7431,16 +7462,7 @@ changedir_func(
post_chdir(scope);
if (dir_differs)
- {
- if (scope == CDSCOPE_WINDOW)
- acmd_fname = (char_u *)"window";
- else if (scope == CDSCOPE_TABPAGE)
- acmd_fname = (char_u *)"tabpage";
- else
- acmd_fname = (char_u *)"global";
- apply_autocmds(EVENT_DIRCHANGED, acmd_fname, new_dir, FALSE,
- curbuf);
- }
+ apply_autocmds(EVENT_DIRCHANGED, acmd_fname, new_dir, FALSE, curbuf);
return TRUE;
}
diff --git a/src/misc2.c b/src/misc2.c
index fac836fb76..38da7e59c4 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -1914,6 +1914,9 @@ vim_chdirfile(char_u *fname, char *trigger_autocmd)
// nothing to do
return OK;
+ if (trigger_autocmd != NULL)
+ trigger_DirChangedPre((char_u *)trigger_autocmd, new_dir);
+
if (mch_chdir((char *)new_dir) != 0)
return FAIL;
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index 0fed2f02df..3be7471070 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -48,6 +48,7 @@ void tabpage_new(void);
void do_exedit(exarg_T *eap, win_T *old_curwin);
void free_cd_dir(void);
void post_chdir(cdscope_T scope);
+void trigger_DirChangedPre(char_u *acmd_fname, char_u *new_dir);
int changedir_func(char_u *new_dir, int forceit, cdscope_T scope);
void ex_cd(exarg_T *eap);
void do_sleep(long msec, int hide_cursor);
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index 1ecb883079..3ff4c3cf5b 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -1922,14 +1922,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
@@ -1950,6 +1952,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
@@ -1957,7 +1960,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/version.c b/src/version.c
index 9ef520ebcb..ab53d51200 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 4335,
+/**/
4334,
/**/
4333,
diff --git a/src/vim.h b/src/vim.h
index 67b4e33c1b..166edf579f 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1304,6 +1304,7 @@ enum auto_event
EVENT_CURSORMOVEDI, // cursor was moved in Insert mode
EVENT_DIFFUPDATED, // after diffs were updated
EVENT_DIRCHANGED, // after user changed directory
+ EVENT_DIRCHANGEDPRE, // before directory changes
EVENT_ENCODINGCHANGED, // after changing the 'encoding' option
EVENT_EXITPRE, // before exiting
EVENT_FILEAPPENDCMD, // append to a file using command