From 82117da5df93666798b94e4e6e47e11dcb1b4dcd Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 11 Mar 2017 17:26:22 +0100 Subject: tabpage_S: Name tp_localdir per convention. --- src/nvim/buffer_defs.h | 3 +-- src/nvim/eval.c | 4 ++-- src/nvim/ex_docmd.c | 6 +++--- src/nvim/window.c | 11 +++++------ 4 files changed, 11 insertions(+), 13 deletions(-) (limited to 'src/nvim') diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index a1b5633c32..3e9767adde 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -825,8 +825,7 @@ struct tabpage_S { frame_T *(tp_snapshot[SNAP_COUNT]); ///< window layout snapshots dictitem_T tp_winvar; ///< variable for "t:" Dictionary dict_T *tp_vars; ///< internal variables, local to tab page - char_u *localdir; ///< Absolute path of local directory or - ///< NULL + char_u *tp_localdir; ///< Absolute path of local CWD or NULL }; /* diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 6dc7e5606e..78f470b10a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -10901,7 +10901,7 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr) } case kCdScopeTab: // FALLTHROUGH assert(tp); - from = tp->localdir; + from = tp->tp_localdir; if (from) { break; } @@ -12015,7 +12015,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr) break; case kCdScopeTab: assert(tp); - rettv->vval.v_number = tp->localdir ? 1 : 0; + rettv->vval.v_number = tp->tp_localdir ? 1 : 0; break; case kCdScopeGlobal: // The global scope never has a local directory diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 87b6959101..146f1b6df6 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6949,8 +6949,8 @@ void post_chdir(CdScope scope) // Overwrite the local directory of the current tab page for `cd` and `tcd` if (scope >= kCdScopeTab) { - xfree(curtab->localdir); - curtab->localdir = NULL; + xfree(curtab->tp_localdir); + curtab->tp_localdir = NULL; } if (scope < kCdScopeGlobal) { @@ -6970,7 +6970,7 @@ void post_chdir(CdScope scope) case kCdScopeTab: // Remember this local directory for the tab page. if (os_dirname(NameBuff, MAXPATHL) == OK) { - curtab->localdir = vim_strsave(NameBuff); + curtab->tp_localdir = vim_strsave(NameBuff); } break; case kCdScopeWindow: diff --git a/src/nvim/window.c b/src/nvim/window.c index 73a60b2e04..0c265a5ede 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2998,8 +2998,7 @@ void free_tabpage(tabpage_T *tp) hash_init(&tp->tp_vars->dv_hashtab); unref_var_dict(tp->tp_vars); - - xfree(tp->localdir); // Free tab-local working directory + xfree(tp->tp_localdir); xfree(tp); } @@ -3025,7 +3024,7 @@ int win_new_tabpage(int after, char_u *filename) return FAIL; } - newtp->localdir = tp->localdir ? vim_strsave(tp->localdir) : NULL; + newtp->tp_localdir = tp->tp_localdir ? vim_strsave(tp->tp_localdir) : NULL; curtab = newtp; @@ -3617,9 +3616,9 @@ 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, of the tab - // or NULL. - char_u *new_dir = curwin->w_localdir ? curwin->w_localdir : curtab->localdir; + // 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; if (new_dir) { // Window/tab has a local directory: Save current directory as global -- cgit From 99a1a58c66b9bc56d98ee7a8d249d594669e9573 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 11 Mar 2017 22:46:20 +0100 Subject: DirChanged: Publish _after_ updating win/tab CWD. So getcwd() works correctly during DirChanged event. Closes #6260 --- src/nvim/ex_docmd.c | 24 +++++++++++------------- src/nvim/file_search.c | 6 +----- 2 files changed, 12 insertions(+), 18 deletions(-) (limited to 'src/nvim') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 146f1b6df6..5ab97d9b9a 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6943,24 +6943,28 @@ void free_cd_dir(void) /// @param scope Scope of the function call (global, tab or window). void post_chdir(CdScope scope) { - // The local directory of the current window is always overwritten. + // Always overwrite the window-local CWD. xfree(curwin->w_localdir); curwin->w_localdir = NULL; - // Overwrite the local directory of the current tab page for `cd` and `tcd` + // Overwrite the tab-local CWD for :cd, :tcd. if (scope >= kCdScopeTab) { xfree(curtab->tp_localdir); curtab->tp_localdir = NULL; } if (scope < kCdScopeGlobal) { - // If still in global directory, need to remember current directory as - // global directory. + // If still in global directory, set CWD as the global directory. if (globaldir == NULL && prev_dir != NULL) { globaldir = vim_strsave(prev_dir); } } + char curdir[MAXPATHL]; + if (os_dirname((char_u *)curdir, MAXPATHL) != OK) { + EMSG2(_(e_intern2), "post_chdir()"); + return; + } switch (scope) { case kCdScopeGlobal: // We are now in the global directory, no need to remember its name. @@ -6968,23 +6972,17 @@ void post_chdir(CdScope scope) globaldir = NULL; break; case kCdScopeTab: - // Remember this local directory for the tab page. - if (os_dirname(NameBuff, MAXPATHL) == OK) { - curtab->tp_localdir = vim_strsave(NameBuff); - } + curtab->tp_localdir = (char_u *)xstrdup(curdir); break; case kCdScopeWindow: - // Remember this local directory for the window. - if (os_dirname(NameBuff, MAXPATHL) == OK) { - curwin->w_localdir = vim_strsave(NameBuff); - } + curwin->w_localdir = (char_u *)xstrdup(curdir); break; case kCdScopeInvalid: - // We should never get here assert(false); } shorten_fnames(TRUE); + do_autocmd_dirchanged(curdir, scope); } /// `:cd`, `:tcd`, `:lcd`, `:chdir`, `:tchdir` and `:lchdir`. diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 79a39c6503..34696ddd7f 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -1519,7 +1519,7 @@ theend: return file_name; } -static void do_autocmd_dirchanged(char_u *new_dir, CdScope scope) +void do_autocmd_dirchanged(char *new_dir, CdScope scope) { static bool recursive = false; @@ -1587,10 +1587,6 @@ int vim_chdir(char_u *new_dir, CdScope scope) } int r = os_chdir((char *)dir_name); - if (r == 0) { - do_autocmd_dirchanged(dir_name, scope); - } - xfree(dir_name); return r; } -- cgit From d9fcbc2cfb5f20f63a2870624ce48a58cf918ea8 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 12 Mar 2017 12:11:10 +0100 Subject: DirChanged: trigger when switching scopes Closes #6054 --- src/nvim/ex_docmd.c | 3 +-- src/nvim/file_search.c | 7 ++++--- src/nvim/memory.c | 7 +++++++ src/nvim/window.c | 36 +++++++++++++++++++++++------------- 4 files changed, 35 insertions(+), 18 deletions(-) (limited to 'src/nvim') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 5ab97d9b9a..745419a98f 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -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) { @@ -6981,7 +6980,7 @@ void post_chdir(CdScope scope) assert(false); } - shorten_fnames(TRUE); + shorten_fnames(true); do_autocmd_dirchanged(curdir, scope); } diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 34696ddd7f..c840c0a2d1 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -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); @@ -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; } diff --git a/src/nvim/memory.c b/src/nvim/memory.c index b593936d7b..58c01fbe7a 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -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. diff --git a/src/nvim/window.c b/src/nvim/window.c index 0c265a5ede..7c7d73fdfb 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -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); -- cgit From c5e61b41a53c4fac93f1101ece1a23168eccb3a3 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 12 Mar 2017 12:12:26 +0100 Subject: DirChanged: avoid redundant events on 'autochdir' --- src/nvim/ex_docmd.c | 10 +++++----- src/nvim/file_search.c | 19 +++++++++++++++---- 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'src/nvim') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 745419a98f..774380b2f0 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6960,8 +6960,8 @@ void post_chdir(CdScope scope) } } - char curdir[MAXPATHL]; - if (os_dirname((char_u *)curdir, MAXPATHL) != OK) { + char cwd[MAXPATHL]; + if (os_dirname((char_u *)cwd, MAXPATHL) != OK) { return; } switch (scope) { @@ -6971,17 +6971,17 @@ void post_chdir(CdScope scope) globaldir = NULL; break; case kCdScopeTab: - curtab->tp_localdir = (char_u *)xstrdup(curdir); + curtab->tp_localdir = (char_u *)xstrdup(cwd); break; case kCdScopeWindow: - curwin->w_localdir = (char_u *)xstrdup(curdir); + curwin->w_localdir = (char_u *)xstrdup(cwd); break; case kCdScopeInvalid: assert(false); } shorten_fnames(true); - do_autocmd_dirchanged(curdir, scope); + do_autocmd_dirchanged(cwd, scope); } /// `:cd`, `:tcd`, `:lcd`, `:chdir`, `:tchdir` and `:lchdir`. diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index c840c0a2d1..b73d9944ce 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -1566,14 +1566,25 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope) /// @return OK or FAIL int vim_chdirfile(char_u *fname) { - char_u dir[MAXPATHL]; + char dir[MAXPATHL]; STRLCPY(dir, fname, MAXPATHL); - *path_tail_with_sep(dir) = NUL; - if (os_chdir((char *)dir) != 0) { + *path_tail_with_sep((char_u *)dir) = NUL; + + if (os_dirname(NameBuff, sizeof(NameBuff)) != OK) { + NameBuff[0] = NUL; + } + + if (os_chdir(dir) != 0) { return FAIL; } - do_autocmd_dirchanged((char *)dir, kCdScopeWindow); + +#ifdef BACKSLASH_IN_FILENAME + slash_adjust(dir); +#endif + if (!strequal(dir, (char *)NameBuff)) { + do_autocmd_dirchanged(dir, kCdScopeWindow); + } return OK; } -- cgit