mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 03:05:11 -07:00
vim-patch:8.0.1459: cannot handle change of directory
Problem: Cannot handle change of directory. Solution: Add the DirChanged autocommand event. (Andy Massimino, closes vim/vim#888) Avoid changing directory for 'autochdir' too often.b7407d3fc9
Only add "auto" pattern. "window" and "global" are already implemented. Skip `Test_dirchanged_auto` using `CheckFunction test_autochdir`. Part of PR #15952. More information can be found there. N/A patches for version.c: vim-patch:8.0.1460: missing file in patch Problem: Missing file in patch. Solution: Add changes to missing file.b5cb65ba2b
vim-patch:8.0.1461: missing another file in patch Problem: Missing another file in patch. Solution: Add changes to missing file.15833239a4
This commit is contained in:
parent
30af69509d
commit
920473d2f2
@ -519,11 +519,17 @@ DiffUpdated After diffs have been updated. Depending on
|
||||
change or when doing |:diffupdate|.
|
||||
*DirChanged*
|
||||
DirChanged After the |current-directory| was changed.
|
||||
The pattern can be:
|
||||
"window" to trigger on `:lcd`
|
||||
"tab" to trigger on `:tcd`
|
||||
"global" to trigger on `:cd`
|
||||
"auto" to trigger on 'autochdir'.
|
||||
Sets these |v:event| keys:
|
||||
cwd: current working directory
|
||||
scope: "global", "tab", "window"
|
||||
changed_window: v:true if we fired the event
|
||||
switching window (or tab)
|
||||
<afile> is set to the new directory name.
|
||||
Non-recursive (event cannot trigger itself).
|
||||
*FileAppendCmd*
|
||||
FileAppendCmd Before appending to a file. Should do the
|
||||
|
@ -180,6 +180,7 @@ Commands:
|
||||
|:match| can be invoked before highlight group is defined
|
||||
|
||||
Events:
|
||||
|DirChanged| can be triggered when switching to another window
|
||||
|Signal|
|
||||
|TabNewEntered|
|
||||
|TermClose|
|
||||
|
@ -593,9 +593,6 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last)
|
||||
buf->b_nwindows--;
|
||||
}
|
||||
|
||||
// Change directories when the 'acd' option is set.
|
||||
do_autochdir();
|
||||
|
||||
// Disable buffer-updates for the current buffer.
|
||||
// No need to check `unload_buf`: in that case the function returned above.
|
||||
buf_updates_unload(buf, false);
|
||||
@ -1628,7 +1625,7 @@ void do_autochdir(void)
|
||||
if (p_acd) {
|
||||
if (starting == 0
|
||||
&& curbuf->b_ffname != NULL
|
||||
&& vim_chdirfile(curbuf->b_ffname) == OK) {
|
||||
&& vim_chdirfile(curbuf->b_ffname, kCdCauseAuto) == OK) {
|
||||
post_chdir(kCdScopeGlobal, false);
|
||||
shorten_fnames(true);
|
||||
}
|
||||
|
@ -7749,7 +7749,7 @@ void post_chdir(CdScope scope, bool trigger_dirchanged)
|
||||
shorten_fnames(true);
|
||||
|
||||
if (trigger_dirchanged) {
|
||||
do_autocmd_dirchanged(cwd, scope, false);
|
||||
do_autocmd_dirchanged(cwd, scope, kCdCauseManual);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -963,7 +963,7 @@ void ex_mkrc(exarg_T *eap)
|
||||
*dirnow = NUL;
|
||||
}
|
||||
if (*dirnow != NUL && (ssop_flags & SSOP_SESDIR)) {
|
||||
if (vim_chdirfile((char_u *)fname) == OK) {
|
||||
if (vim_chdirfile((char_u *)fname, kCdCauseOther) == OK) {
|
||||
shorten_fnames(true);
|
||||
}
|
||||
} else if (*dirnow != NUL
|
||||
|
@ -1590,7 +1590,7 @@ theend:
|
||||
return file_name;
|
||||
}
|
||||
|
||||
void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window)
|
||||
void do_autocmd_dirchanged(char *new_dir, CdScope scope, CdCause cause)
|
||||
{
|
||||
static bool recursive = false;
|
||||
|
||||
@ -1621,10 +1621,22 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window)
|
||||
}
|
||||
|
||||
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"), changed_window);
|
||||
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);
|
||||
|
||||
switch (cause) {
|
||||
case kCdCauseManual:
|
||||
case kCdCauseWindow:
|
||||
break;
|
||||
case kCdCauseAuto:
|
||||
snprintf(buf, sizeof(buf), "auto");
|
||||
break;
|
||||
case kCdCauseOther:
|
||||
// Should never happen.
|
||||
abort();
|
||||
}
|
||||
|
||||
apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, (char_u *)new_dir, false,
|
||||
curbuf);
|
||||
|
||||
@ -1636,7 +1648,7 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window)
|
||||
/// Change to a file's directory.
|
||||
/// Caller must call shorten_fnames()!
|
||||
/// @return OK or FAIL
|
||||
int vim_chdirfile(char_u *fname)
|
||||
int vim_chdirfile(char_u *fname, CdCause cause)
|
||||
{
|
||||
char dir[MAXPATHL];
|
||||
|
||||
@ -1654,8 +1666,8 @@ int vim_chdirfile(char_u *fname)
|
||||
#ifdef BACKSLASH_IN_FILENAME
|
||||
slash_adjust((char_u *)dir);
|
||||
#endif
|
||||
if (!strequal(dir, (char *)NameBuff)) {
|
||||
do_autocmd_dirchanged(dir, kCdScopeWindow, false);
|
||||
if (cause != kCdCauseOther && !strequal(dir, (char *)NameBuff)) {
|
||||
do_autocmd_dirchanged(dir, kCdScopeWindow, cause);
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -1042,6 +1042,14 @@ typedef enum {
|
||||
#define MIN_CD_SCOPE kCdScopeWindow
|
||||
#define MAX_CD_SCOPE kCdScopeGlobal
|
||||
|
||||
/// What caused the current directory to change.
|
||||
typedef enum {
|
||||
kCdCauseOther = -1,
|
||||
kCdCauseManual, ///< Using `:cd`, `:tcd`, `:lcd` or `chdir()`.
|
||||
kCdCauseWindow, ///< Switching to another window.
|
||||
kCdCauseAuto, ///< On 'autochdir'.
|
||||
} CdCause;
|
||||
|
||||
// Only filled for Win32.
|
||||
EXTERN char windowsVersion[20] INIT(= { 0 });
|
||||
|
||||
|
@ -1328,6 +1328,62 @@ func Test_autocommand_all_events()
|
||||
call assert_fails('au * x bwipe', 'E1155:')
|
||||
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
|
||||
|
||||
" Test TextChangedI and TextChangedP
|
||||
" See test/functional/viml/completion_spec.lua'
|
||||
func Test_ChangedP()
|
||||
|
@ -4542,7 +4542,7 @@ static void win_enter_ext(win_T *const wp, const int flags)
|
||||
if (os_chdir(new_dir) == 0) {
|
||||
if (!p_acd && !strequal(new_dir, cwd)) {
|
||||
do_autocmd_dirchanged(new_dir, curwin->w_localdir
|
||||
? kCdScopeWindow : kCdScopeTab, true);
|
||||
? kCdScopeWindow : kCdScopeTab, kCdCauseWindow);
|
||||
}
|
||||
shorten_fnames(true);
|
||||
}
|
||||
@ -4551,7 +4551,7 @@ static void win_enter_ext(win_T *const wp, const int flags)
|
||||
// directory: Change to the global directory.
|
||||
if (os_chdir((char *)globaldir) == 0) {
|
||||
if (!p_acd && !strequal((char *)globaldir, cwd)) {
|
||||
do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, true);
|
||||
do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, kCdCauseWindow);
|
||||
}
|
||||
}
|
||||
XFREE_CLEAR(globaldir);
|
||||
|
Loading…
Reference in New Issue
Block a user