]> granicus.if.org Git - vim/commitdiff
patch 8.0.1459: cannot handle change of directory v8.0.1459
authorBram Moolenaar <Bram@vim.org>
Sat, 3 Feb 2018 16:36:27 +0000 (17:36 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 3 Feb 2018 16:36:27 +0000 (17:36 +0100)
Problem:    Cannot handle change of directory.
Solution:   Add the DirChanged autocommand event. (Andy Massimino,
            closes #888)  Avoid changing directory for 'autochdir' too often.

12 files changed:
runtime/doc/autocmd.txt
src/buffer.c
src/ex_docmd.c
src/fileio.c
src/gui_mac.c
src/main.c
src/netbeans.c
src/os_win32.c
src/proto/misc2.pro
src/testdir/test_autocmd.vim
src/version.c
src/vim.h

index 4adf007e7b895ed0c95cbe2c4813cce1dec28c55..350ae7e88f41a602ad91f5d02f97bc28a6f5b4b6 100644 (file)
@@ -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.
index ecd8f4eb65e54107987aace1737328a96f67c255..c0d3d3d9fc4122eedb129a8339f91b9166c60edc 100644 (file)
@@ -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
index 539e39fb425356e1c650facd2de268be579125c8..cd915c9daeaf513581117c3498259e727f80e9d8 100644 (file)
@@ -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
index fb5af64466e65beefc39f4df7c803e059be74e5f..ab216abbf6984438d9b6ce3fac14799a71a828e3 100644 (file)
@@ -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);
index db9f9597f4b629278897c2c085a4d2bbe5ce3fbe..6386b639a6bdd398d1676293fb7977ad84c09ef7 100644 (file)
@@ -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;
index aea652b5d32c29b31b1e43547052a7b99143b57b..9f443aef252044781158d65404cd4b2fa79e0840 100644 (file)
@@ -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);
index c906d289120eb00a35298528e383b04e8397ee3d..199cfd63cd817036f7b6089167f731a2e917cc4e 100644 (file)
@@ -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);
 }
 
index d356c7ed6873c6de75833647e0af4f476e03a755..a42df6f29f14a45347f74a57942a74c7f2aa33b5 100644 (file)
@@ -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();
index 68c40daa1fe759e5d1efbbaf18dcc5e54cef5d27..6999683c7bdbe6ede047ac8f39c036c728bee278 100644 (file)
@@ -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);
index b7d43b59adaa75672e064feb8053989b14654380..c504f704fc72ba1d696f4626faa0b78d8ce04ab9 100644 (file)
@@ -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
index c836d3fd874fa6fb83a888d65995b1c40e702402..4706262acd818b79bbeb3d43a608c9a9a2382503 100644 (file)
@@ -771,6 +771,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1459,
 /**/
     1458,
 /**/
index 1f9671a187639cf4544bf1a37d755d80a4cd40e9..ad372351e5495ca55f19663e5e7808cc689ba5c3 100644 (file)
--- 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 */