summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/autocmd.txt12
-rw-r--r--src/buffer.c7
-rw-r--r--src/ex_docmd.c12
-rw-r--r--src/fileio.c6
-rw-r--r--src/gui_mac.c3
-rw-r--r--src/main.c4
-rw-r--r--src/netbeans.c2
-rw-r--r--src/os_win32.c2
-rw-r--r--src/proto/misc2.pro2
-rw-r--r--src/testdir/test_autocmd.vim56
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h1
12 files changed, 94 insertions, 15 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index 4adf007e7..350ae7e88 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -295,6 +295,8 @@ Name triggered by ~
|FileChangedShellPost| After handling a file changed since editing started
|FileChangedRO| before making the first change to a read-only file
+|DirChanged| after the working directory has changed
+
|ShellCmdPost| after executing a shell command
|ShellFilterPost| after filtering with a shell command
@@ -633,6 +635,16 @@ FileChangedRO Before making the first change to a read-only
*E881*
If the number of lines changes saving for undo
may fail and the change will be aborted.
+ *DirChanged*
+DirChanged The working directory has changed in response
+ to the |:cd| or |:lcd| commands, or as a
+ result of the 'autochdir' option.
+ The pattern can be:
+ "window" to trigger on `:lcd
+ "global" to trigger on `:cd`
+ "auto" to trigger on 'autochdir'.
+ "drop" to trigger on editing a file
+ <afile> is set to the new directory name.
*FileChangedShell*
FileChangedShell When Vim notices that the modification time of
a file has changed since editing started.
diff --git a/src/buffer.c b/src/buffer.c
index ecd8f4eb6..c0d3d3d9f 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -595,7 +595,7 @@ aucmd_abort:
#ifdef FEAT_DIFF
if (diffopt_hiddenoff() && !unload_buf && buf->b_nwindows == 0)
- diff_buf_delete(buf); /* Clear 'diff' for hidden buffer. */
+ diff_buf_delete(buf); /* Clear 'diff' for hidden buffer. */
#endif
/* Return when a window is displaying the buffer or when it's not
@@ -657,9 +657,6 @@ aucmd_abort:
--buf->b_nwindows;
#endif
- /* Change directories when the 'acd' option is set. */
- DO_AUTOCHDIR
-
/*
* Remove the buffer from the list.
*/
@@ -1862,7 +1859,7 @@ do_autochdir(void)
{
if ((starting == 0 || test_autochdir)
&& curbuf->b_ffname != NULL
- && vim_chdirfile(curbuf->b_ffname) == OK)
+ && vim_chdirfile(curbuf->b_ffname, "auto") == OK)
shorten_fnames(TRUE);
}
#endif
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 539e39fb4..cd915c9da 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -9048,11 +9048,19 @@ ex_cd(exarg_T *eap)
EMSG(_(e_failed));
else
{
- post_chdir(eap->cmdidx == CMD_lcd || eap->cmdidx == CMD_lchdir);
+ int is_local_chdir = eap->cmdidx == CMD_lcd
+ || eap->cmdidx == CMD_lchdir;
+
+ post_chdir(is_local_chdir);
/* Echo the new current directory if the command was typed. */
if (KeyTyped || p_verbose >= 5)
ex_pwd(eap);
+#ifdef FEAT_AUTOCMD
+ apply_autocmds(EVENT_DIRCHANGED,
+ is_local_chdir ? (char_u *)"window" : (char_u *)"global",
+ new_dir, FALSE, curbuf);
+#endif
}
vim_free(tofree);
}
@@ -9932,7 +9940,7 @@ ex_mkrc(
*dirnow = NUL;
if (*dirnow != NUL && (ssop_flags & SSOP_SESDIR))
{
- if (vim_chdirfile(fname) == OK)
+ if (vim_chdirfile(fname, NULL) == OK)
shorten_fnames(TRUE);
}
else if (*dirnow != NUL
diff --git a/src/fileio.c b/src/fileio.c
index fb5af6446..ab216abbf 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -7798,6 +7798,7 @@ static struct event_name
{"CursorHoldI", EVENT_CURSORHOLDI},
{"CursorMoved", EVENT_CURSORMOVED},
{"CursorMovedI", EVENT_CURSORMOVEDI},
+ {"DirChanged", EVENT_DIRCHANGED},
{"EncodingChanged", EVENT_ENCODINGCHANGED},
{"FileEncoding", EVENT_ENCODINGCHANGED},
{"FileAppendPost", EVENT_FILEAPPENDPOST},
@@ -9588,7 +9589,7 @@ apply_autocmds_group(
{
sfname = vim_strsave(fname);
/* Don't try expanding FileType, Syntax, FuncUndefined, WindowID,
- * ColorScheme or QuickFixCmd* */
+ * ColorScheme, QuickFixCmd* or DirChanged */
if (event == EVENT_FILETYPE
|| event == EVENT_SYNTAX
|| event == EVENT_FUNCUNDEFINED
@@ -9597,7 +9598,8 @@ apply_autocmds_group(
|| event == EVENT_QUICKFIXCMDPRE
|| event == EVENT_COLORSCHEME
|| event == EVENT_OPTIONSET
- || event == EVENT_QUICKFIXCMDPOST)
+ || event == EVENT_QUICKFIXCMDPOST
+ || event == EVENT_DIRCHANGED)
fname = vim_strsave(fname);
else
fname = FullName_save(fname, FALSE);
diff --git a/src/gui_mac.c b/src/gui_mac.c
index db9f9597f..6386b639a 100644
--- a/src/gui_mac.c
+++ b/src/gui_mac.c
@@ -1105,7 +1105,8 @@ HandleODocAE(const AppleEvent *theAEvent, AppleEvent *theReply, long refCon)
}
/* Change directory to the location of the first file. */
- if (GARGCOUNT > 0 && vim_chdirfile(alist_name(&GARGLIST[0])) == OK)
+ if (GARGCOUNT > 0
+ && vim_chdirfile(alist_name(&GARGLIST[0]), "drop") == OK)
shorten_fnames(TRUE);
goto finished;
diff --git a/src/main.c b/src/main.c
index aea652b5d..9f443aef2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -264,7 +264,7 @@ main
* Hint: to avoid this when typing a command use a forward slash.
* If the cd fails, it doesn't matter.
*/
- (void)vim_chdirfile(params.fname);
+ (void)vim_chdirfile(params.fname, "drop");
if (start_dir != NULL)
mch_dirname(start_dir, MAXPATHL);
}
@@ -314,7 +314,7 @@ main
&& STRCMP(NameBuff, "/") == 0)
{
if (params.fname != NULL)
- (void)vim_chdirfile(params.fname);
+ (void)vim_chdirfile(params.fname, "drop");
else
{
expand_env((char_u *)"$HOME", NameBuff, MAXPATHL);
diff --git a/src/netbeans.c b/src/netbeans.c
index c906d2891..199cfd63c 100644
--- a/src/netbeans.c
+++ b/src/netbeans.c
@@ -2663,7 +2663,7 @@ netbeans_file_opened(buf_T *bufp)
nbdebug(("EVT: %s", buffer));
nb_send(buffer, "netbeans_file_opened");
- if (p_acd && vim_chdirfile(bufp->b_ffname) == OK)
+ if (p_acd && vim_chdirfile(bufp->b_ffname, "auto") == OK)
shorten_fnames(TRUE);
}
diff --git a/src/os_win32.c b/src/os_win32.c
index d356c7ed6..a42df6f29 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -7193,7 +7193,7 @@ fix_arg_enc(void)
{
do_cmdline_cmd((char_u *)":rewind");
if (GARGCOUNT == 1 && used_file_full_path)
- (void)vim_chdirfile(alist_name(&GARGLIST[0]));
+ (void)vim_chdirfile(alist_name(&GARGLIST[0]), "drop");
}
set_alist_count();
diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro
index 68c40daa1..6999683c7 100644
--- a/src/proto/misc2.pro
+++ b/src/proto/misc2.pro
@@ -82,7 +82,7 @@ int call_shell(char_u *cmd, int opt);
int get_real_state(void);
int after_pathsep(char_u *b, char_u *p);
int same_directory(char_u *f1, char_u *f2);
-int vim_chdirfile(char_u *fname);
+int vim_chdirfile(char_u *fname, char *trigger_autocmd);
int vim_stat(const char *name, stat_T *stp);
char_u *parse_shape_opt(int what);
int get_shape_idx(int mouse);
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index b7d43b59a..c504f704f 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -1190,3 +1190,59 @@ func Test_nocatch_wipe_dummy_buffer()
call assert_fails('lvĀ½ /x', 'E480')
au!
endfunc
+
+function s:Before_test_dirchanged()
+ augroup test_dirchanged
+ autocmd!
+ augroup END
+ let s:li = []
+ let s:dir_this = getcwd()
+ let s:dir_other = s:dir_this . '/foo'
+ call mkdir(s:dir_other)
+endfunc
+
+function s:After_test_dirchanged()
+ exe 'cd' s:dir_this
+ call delete(s:dir_other, 'd')
+ augroup test_dirchanged
+ autocmd!
+ augroup END
+endfunc
+
+function Test_dirchanged_global()
+ call s:Before_test_dirchanged()
+ autocmd test_dirchanged DirChanged global call add(s:li, "cd:")
+ autocmd test_dirchanged DirChanged global call add(s:li, expand("<afile>"))
+ exe 'cd' s:dir_other
+ call assert_equal(["cd:", s:dir_other], s:li)
+ exe 'lcd' s:dir_other
+ call assert_equal(["cd:", s:dir_other], s:li)
+ call s:After_test_dirchanged()
+endfunc
+
+function Test_dirchanged_local()
+ call s:Before_test_dirchanged()
+ autocmd test_dirchanged DirChanged window call add(s:li, "lcd:")
+ autocmd test_dirchanged DirChanged window call add(s:li, expand("<afile>"))
+ exe 'cd' s:dir_other
+ call assert_equal([], s:li)
+ exe 'lcd' s:dir_other
+ call assert_equal(["lcd:", s:dir_other], s:li)
+ call s:After_test_dirchanged()
+endfunc
+
+function Test_dirchanged_auto()
+ call s:Before_test_dirchanged()
+ call test_autochdir()
+ autocmd test_dirchanged DirChanged auto call add(s:li, "auto:")
+ autocmd test_dirchanged DirChanged auto call add(s:li, expand("<afile>"))
+ set acd
+ exe 'cd ..'
+ call assert_equal([], s:li)
+ exe 'edit ' . s:dir_other . '/Xfile'
+ call assert_equal(s:dir_other, getcwd())
+ call assert_equal(["auto:", s:dir_other], s:li)
+ set noacd
+ bwipe!
+ call s:After_test_dirchanged()
+endfunc
diff --git a/src/version.c b/src/version.c
index c836d3fd8..4706262ac 100644
--- a/src/version.c
+++ b/src/version.c
@@ -772,6 +772,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1459,
+/**/
1458,
/**/
1457,
diff --git a/src/vim.h b/src/vim.h
index 1f9671a18..ad372351e 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1276,6 +1276,7 @@ enum auto_event
EVENT_CMDWINLEAVE, /* before leaving the cmdline window */
EVENT_COLORSCHEME, /* after loading a colorscheme */
EVENT_COMPLETEDONE, /* after finishing insert complete */
+ EVENT_DIRCHANGED, /* after changing directory as a result of user cmd */
EVENT_FILEAPPENDPOST, /* after appending to a file */
EVENT_FILEAPPENDPRE, /* before appending to a file */
EVENT_FILEAPPENDCMD, /* append to a file using command */