To: vim_dev@googlegroups.com Subject: Patch 8.0.1459 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1459 Problem: Cannot handle change of directory. Solution: Add the DirChanged autocommand event. (Andy Massimino, closes #888) Avoid changing directory for 'autochdir' too often. Files: runtime/doc/autocmd.txt, src/buffer.c, src/ex_docmd.c, src/fileio.c, src/main.c, src/vim.h, src/proto/misc2.pro, src/gui_mac.c, src/netbeans.c, src/os_win32.c, src/testdir/test_autocmd.vim *** ../vim-8.0.1458/runtime/doc/autocmd.txt 2018-01-31 15:48:01.101171621 +0100 --- runtime/doc/autocmd.txt 2018-02-03 16:29:17.563789718 +0100 *************** *** 279,284 **** --- 295,302 ---- |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 *************** *** 617,622 **** --- 635,650 ---- *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 + is set to the new directory name. *FileChangedShell* FileChangedShell When Vim notices that the modification time of a file has changed since editing started. *** ../vim-8.0.1458/src/buffer.c 2018-01-28 17:05:12.409577523 +0100 --- src/buffer.c 2018-02-03 17:21:38.506982331 +0100 *************** *** 595,601 **** #ifdef FEAT_DIFF if (diffopt_hiddenoff() && !unload_buf && buf->b_nwindows == 0) ! diff_buf_delete(buf); /* Clear 'diff' for hidden buffer. */ #endif /* Return when a window is displaying the buffer or when it's not --- 595,601 ---- #ifdef FEAT_DIFF if (diffopt_hiddenoff() && !unload_buf && buf->b_nwindows == 0) ! diff_buf_delete(buf); /* Clear 'diff' for hidden buffer. */ #endif /* Return when a window is displaying the buffer or when it's not *************** *** 657,665 **** --buf->b_nwindows; #endif - /* Change directories when the 'acd' option is set. */ - DO_AUTOCHDIR - /* * Remove the buffer from the list. */ --- 657,662 ---- *************** *** 1862,1868 **** { if ((starting == 0 || test_autochdir) && curbuf->b_ffname != NULL ! && vim_chdirfile(curbuf->b_ffname) == OK) shorten_fnames(TRUE); } #endif --- 1859,1865 ---- { if ((starting == 0 || test_autochdir) && curbuf->b_ffname != NULL ! && vim_chdirfile(curbuf->b_ffname, "auto") == OK) shorten_fnames(TRUE); } #endif *** ../vim-8.0.1458/src/ex_docmd.c 2017-12-19 21:23:16.817960377 +0100 --- src/ex_docmd.c 2018-02-03 16:22:43.830837612 +0100 *************** *** 9048,9058 **** EMSG(_(e_failed)); else { ! post_chdir(eap->cmdidx == CMD_lcd || eap->cmdidx == CMD_lchdir); /* Echo the new current directory if the command was typed. */ if (KeyTyped || p_verbose >= 5) ex_pwd(eap); } vim_free(tofree); } --- 9048,9066 ---- EMSG(_(e_failed)); else { ! 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,9938 **** *dirnow = NUL; if (*dirnow != NUL && (ssop_flags & SSOP_SESDIR)) { ! if (vim_chdirfile(fname) == OK) shorten_fnames(TRUE); } else if (*dirnow != NUL --- 9940,9946 ---- *dirnow = NUL; if (*dirnow != NUL && (ssop_flags & SSOP_SESDIR)) { ! if (vim_chdirfile(fname, NULL) == OK) shorten_fnames(TRUE); } else if (*dirnow != NUL *** ../vim-8.0.1458/src/fileio.c 2018-01-31 15:48:01.105171594 +0100 --- src/fileio.c 2018-02-03 16:23:05.646667454 +0100 *************** *** 7798,7803 **** --- 7798,7804 ---- {"CursorHoldI", EVENT_CURSORHOLDI}, {"CursorMoved", EVENT_CURSORMOVED}, {"CursorMovedI", EVENT_CURSORMOVEDI}, + {"DirChanged", EVENT_DIRCHANGED}, {"EncodingChanged", EVENT_ENCODINGCHANGED}, {"FileEncoding", EVENT_ENCODINGCHANGED}, {"FileAppendPost", EVENT_FILEAPPENDPOST}, *************** *** 9588,9594 **** { sfname = vim_strsave(fname); /* Don't try expanding FileType, Syntax, FuncUndefined, WindowID, ! * ColorScheme or QuickFixCmd* */ if (event == EVENT_FILETYPE || event == EVENT_SYNTAX || event == EVENT_FUNCUNDEFINED --- 9589,9595 ---- { sfname = vim_strsave(fname); /* Don't try expanding FileType, Syntax, FuncUndefined, WindowID, ! * ColorScheme, QuickFixCmd* or DirChanged */ if (event == EVENT_FILETYPE || event == EVENT_SYNTAX || event == EVENT_FUNCUNDEFINED *************** *** 9597,9603 **** || event == EVENT_QUICKFIXCMDPRE || event == EVENT_COLORSCHEME || event == EVENT_OPTIONSET ! || event == EVENT_QUICKFIXCMDPOST) fname = vim_strsave(fname); else fname = FullName_save(fname, FALSE); --- 9598,9605 ---- || event == EVENT_QUICKFIXCMDPRE || event == EVENT_COLORSCHEME || event == EVENT_OPTIONSET ! || event == EVENT_QUICKFIXCMDPOST ! || event == EVENT_DIRCHANGED) fname = vim_strsave(fname); else fname = FullName_save(fname, FALSE); *** ../vim-8.0.1458/src/main.c 2018-02-03 14:46:41.398054549 +0100 --- src/main.c 2018-02-03 16:14:42.046664018 +0100 *************** *** 264,270 **** * 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); if (start_dir != NULL) mch_dirname(start_dir, MAXPATHL); } --- 264,270 ---- * 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, "drop"); if (start_dir != NULL) mch_dirname(start_dir, MAXPATHL); } *************** *** 314,320 **** && STRCMP(NameBuff, "/") == 0) { if (params.fname != NULL) ! (void)vim_chdirfile(params.fname); else { expand_env((char_u *)"$HOME", NameBuff, MAXPATHL); --- 314,320 ---- && STRCMP(NameBuff, "/") == 0) { if (params.fname != NULL) ! (void)vim_chdirfile(params.fname, "drop"); else { expand_env((char_u *)"$HOME", NameBuff, MAXPATHL); *** ../vim-8.0.1458/src/vim.h 2018-01-31 15:48:01.105171594 +0100 --- src/vim.h 2018-02-03 16:02:07.185321348 +0100 *************** *** 1276,1281 **** --- 1276,1282 ---- 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 */ *** ../vim-8.0.1458/src/proto/misc2.pro 2017-03-12 19:22:31.740585042 +0100 --- src/proto/misc2.pro 2018-02-03 16:15:56.694059861 +0100 *************** *** 82,88 **** 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_stat(const char *name, stat_T *stp); char_u *parse_shape_opt(int what); int get_shape_idx(int mouse); --- 82,88 ---- 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, 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); *** ../vim-8.0.1458/src/gui_mac.c 2018-01-31 21:09:57.635847521 +0100 --- src/gui_mac.c 2018-02-03 16:13:44.347134965 +0100 *************** *** 1105,1111 **** } /* Change directory to the location of the first file. */ ! if (GARGCOUNT > 0 && vim_chdirfile(alist_name(&GARGLIST[0])) == OK) shorten_fnames(TRUE); goto finished; --- 1105,1112 ---- } /* Change directory to the location of the first file. */ ! if (GARGCOUNT > 0 ! && vim_chdirfile(alist_name(&GARGLIST[0]), "drop") == OK) shorten_fnames(TRUE); goto finished; *** ../vim-8.0.1458/src/netbeans.c 2018-01-31 20:51:40.305835913 +0100 --- src/netbeans.c 2018-02-03 16:16:19.253878301 +0100 *************** *** 2663,2669 **** nbdebug(("EVT: %s", buffer)); nb_send(buffer, "netbeans_file_opened"); ! if (p_acd && vim_chdirfile(bufp->b_ffname) == OK) shorten_fnames(TRUE); } --- 2663,2669 ---- nbdebug(("EVT: %s", buffer)); nb_send(buffer, "netbeans_file_opened"); ! if (p_acd && vim_chdirfile(bufp->b_ffname, "auto") == OK) shorten_fnames(TRUE); } *** ../vim-8.0.1458/src/os_win32.c 2017-12-05 15:14:39.195947423 +0100 --- src/os_win32.c 2018-02-03 16:16:52.769609375 +0100 *************** *** 7193,7199 **** { do_cmdline_cmd((char_u *)":rewind"); if (GARGCOUNT == 1 && used_file_full_path) ! (void)vim_chdirfile(alist_name(&GARGLIST[0])); } set_alist_count(); --- 7193,7199 ---- { do_cmdline_cmd((char_u *)":rewind"); if (GARGCOUNT == 1 && used_file_full_path) ! (void)vim_chdirfile(alist_name(&GARGLIST[0]), "drop"); } set_alist_count(); *** ../vim-8.0.1458/src/testdir/test_autocmd.vim 2018-01-31 15:48:01.105171594 +0100 --- src/testdir/test_autocmd.vim 2018-02-03 17:34:49.326760694 +0100 *************** *** 1190,1192 **** --- 1190,1248 ---- 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("")) + 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("")) + 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("")) + 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 *** ../vim-8.0.1458/src/version.c 2018-02-03 15:55:44.377562581 +0100 --- src/version.c 2018-02-03 16:02:50.928890936 +0100 *************** *** 773,774 **** --- 773,776 ---- { /* Add new patch number below this line */ + /**/ + 1459, /**/ -- TALL KNIGHT OF NI: Ni! "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///