Skip to content

Commit

Permalink
DirChanged: trigger when switching scopes
Browse files Browse the repository at this point in the history
Closes #6054
  • Loading branch information
justinmk committed Mar 12, 2017
1 parent 99a1a58 commit d9fcbc2
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 18 deletions.
3 changes: 1 addition & 2 deletions src/nvim/ex_docmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -6962,7 +6962,6 @@ void post_chdir(CdScope scope)

char curdir[MAXPATHL];
if (os_dirname((char_u *)curdir, MAXPATHL) != OK) {
EMSG2(_(e_intern2), "post_chdir()");
return;
}
switch (scope) {
Expand All @@ -6981,7 +6980,7 @@ void post_chdir(CdScope scope)
assert(false);
}

shorten_fnames(TRUE);
shorten_fnames(true);
do_autocmd_dirchanged(curdir, scope);
}

Expand Down
7 changes: 4 additions & 3 deletions src/nvim/file_search.c
Original file line number Diff line number Diff line change
Expand Up @@ -1550,10 +1550,11 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope)
}

dict_add_nr_str(dict, "scope", 0L, (char_u *)buf);
dict_add_nr_str(dict, "cwd", 0L, new_dir);
dict_add_nr_str(dict, "cwd", 0L, (char_u *)new_dir);
dict_set_keys_readonly(dict);

apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, new_dir, false, NULL);
apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, (char_u *)new_dir, false,
NULL);

dict_clear(dict);

Expand All @@ -1572,7 +1573,7 @@ int vim_chdirfile(char_u *fname)
if (os_chdir((char *)dir) != 0) {
return FAIL;
}
do_autocmd_dirchanged(dir, kCdScopeWindow);
do_autocmd_dirchanged((char *)dir, kCdScopeWindow);

return OK;
}
Expand Down
7 changes: 7 additions & 0 deletions src/nvim/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,13 @@ void *xmemdup(const void *data, size_t len)
return memcpy(xmalloc(len), data, len);
}

/// Returns true if strings `a` and `b` are equal. Arguments may be NULL.
bool strequal(const char *a, const char *b)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
return (a == NULL && b == NULL) || (a && b && strcmp(a, b) == 0);
}

/*
* Avoid repeating the error message many times (they take 1 second each).
* Did_outofmem_msg is reset when a character is read.
Expand Down
36 changes: 23 additions & 13 deletions src/nvim/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -3616,28 +3616,38 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid,
curwin->w_cursor.coladd = 0;
changed_line_abv_curs(); /* assume cursor position needs updating */

// The new directory is either the local directory of the window, tab or NULL.
char_u *new_dir = curwin->w_localdir
? curwin->w_localdir : curtab->tp_localdir;
// New directory is either the local directory of the window, tab or NULL.
char *new_dir = (char *)(curwin->w_localdir
? curwin->w_localdir : curtab->tp_localdir);

char cwd[MAXPATHL];
if (os_dirname((char_u *)cwd, MAXPATHL) != OK) {
cwd[0] = NUL;
}

if (new_dir) {
// Window/tab has a local directory: Save current directory as global
// directory (unless that was done already) and change to the local
// directory.
// (unless that was done already) and change to the local directory.
if (globaldir == NULL) {
char_u cwd[MAXPATHL];

if (os_dirname(cwd, MAXPATHL) == OK) {
globaldir = vim_strsave(cwd);
if (cwd[0] != NUL) {
globaldir = (char_u *)xstrdup(cwd);
}
}
if (os_chdir((char *)new_dir) == 0) {
if (os_chdir(new_dir) == 0) {
if (!p_acd && !strequal(new_dir, cwd)) {
do_autocmd_dirchanged(new_dir, curwin->w_localdir
? kCdScopeWindow : kCdScopeTab);
}
shorten_fnames(true);
}
} else if (globaldir != NULL) {
/* Window doesn't have a local directory and we are not in the global
* directory: Change to the global directory. */
ignored = os_chdir((char *)globaldir);
// Window doesn't have a local directory and we are not in the global
// 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);
}
}
xfree(globaldir);
globaldir = NULL;
shorten_fnames(TRUE);
Expand Down
28 changes: 28 additions & 0 deletions test/functional/autocmd/dirchanged_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,34 @@ describe('autocmd DirChanged', function()
eq({cwd=dirs[2], scope='window'}, eval('g:event'))
end)

it("is triggered by switching to win/tab with different CWD #6054", function()
command('lcd '..dirs[3]) -- window 3
command('split '..dirs[2]..'/foo') -- window 2
command('lcd '..dirs[2])
command('split '..dirs[1]..'/bar') -- window 1
command('lcd '..dirs[1])

command('2wincmd w') -- window 2
eq({cwd=dirs[2], scope='window'}, eval('g:event'))

eq(4, eval('g:cdcount'))
command('tabnew') -- tab 2 (tab-local CWD)
eq(4, eval('g:cdcount')) -- same CWD, no DirChanged event
command('tcd '..dirs[3])
command('tabnext') -- tab 1 (no tab-local CWD)
eq({cwd=dirs[2], scope='window'}, eval('g:event'))
command('tabnext') -- tab 2
eq({cwd=dirs[3], scope='tab'}, eval('g:event'))
eq(7, eval('g:cdcount'))

command('tabnext') -- tab 1
command('3wincmd w') -- window 3
eq(9, eval('g:cdcount'))
command('tabnext') -- tab 2 (has the *same* CWD)
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event

end)

it('is triggered by nvim_set_current_dir()', function()
request('nvim_set_current_dir', dirs[1])
eq({cwd=dirs[1], scope='global'}, eval('g:event'))
Expand Down

0 comments on commit d9fcbc2

Please sign in to comment.