diff options
author | Marco Hinz <mh.codebro@gmail.com> | 2017-01-16 13:36:16 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-16 13:36:16 +0100 |
commit | 340f79b4b8f1021f4a3b88265ced2ce39d0e2e03 (patch) | |
tree | 71509fab0581f8454272493e38fd0018a32c3c5f /src | |
parent | fa94c4c2d917b70df443ba0ebcd87da35dc1bb30 (diff) | |
parent | 1f7a119f5efc13fbce6446bf268c2e0f9d753147 (diff) | |
download | rneovim-340f79b4b8f1021f4a3b88265ced2ce39d0e2e03.tar.gz rneovim-340f79b4b8f1021f4a3b88265ced2ce39d0e2e03.tar.bz2 rneovim-340f79b4b8f1021f4a3b88265ced2ce39d0e2e03.zip |
Merge #5928 'New event: DirChanged'
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/vim.c | 2 | ||||
-rw-r--r-- | src/nvim/auevents.lua | 2 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 41 | ||||
-rw-r--r-- | src/nvim/ex_docmd.h | 15 | ||||
-rw-r--r-- | src/nvim/file_search.c | 56 | ||||
-rw-r--r-- | src/nvim/fileio.c | 10 | ||||
-rw-r--r-- | src/nvim/globals.h | 16 | ||||
-rw-r--r-- | src/nvim/ops.c | 6 | ||||
-rw-r--r-- | src/nvim/types.h | 1 |
9 files changed, 103 insertions, 46 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index b17b59f7a6..f37e996f06 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -315,7 +315,7 @@ void nvim_set_current_dir(String dir, Error *err) try_start(); - if (vim_chdir((char_u *)string)) { + if (vim_chdir((char_u *)string, kCdScopeGlobal)) { if (!try_end(err)) { api_set_error(err, Exception, _("Failed to change directory")); } diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index b405928577..68a47c244f 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -28,6 +28,7 @@ return { 'CursorHoldI', -- idem, in Insert mode 'CursorMoved', -- cursor was moved 'CursorMovedI', -- cursor was moved in Insert mode + 'DirChanged', -- directory changed 'EncodingChanged', -- after changing the 'encoding' option 'FileAppendCmd', -- append to a file using command 'FileAppendPost', -- after appending to a file @@ -102,6 +103,7 @@ return { -- List of neovim-specific events or aliases for the purpose of generating -- syntax file neovim_specific = { + DirChanged=true, TabClosed=true, TabNew=true, TabNewEntered=true, diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 5ff79bcfef..e205901635 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6998,8 +6998,6 @@ void post_chdir(CdScope scope) shorten_fnames(TRUE); } - - /// `:cd`, `:tcd`, `:lcd`, `:chdir`, `:tchdir` and `:lchdir`. void ex_cd(exarg_T *eap) { @@ -7041,30 +7039,31 @@ void ex_cd(exarg_T *eap) new_dir = NameBuff; } #endif - if (vim_chdir(new_dir)) { - EMSG(_(e_failed)); - } else { - CdScope scope = kCdScopeGlobal; // Depends on command invoked + CdScope scope = kCdScopeGlobal; // Depends on command invoked - switch (eap->cmdidx) { - case CMD_tcd: - case CMD_tchdir: - scope = kCdScopeTab; - break; - case CMD_lcd: - case CMD_lchdir: - scope = kCdScopeWindow; - break; - default: - break; - } + switch (eap->cmdidx) { + case CMD_tcd: + case CMD_tchdir: + scope = kCdScopeTab; + break; + case CMD_lcd: + case CMD_lchdir: + scope = kCdScopeWindow; + break; + default: + break; + } + if (vim_chdir(new_dir, scope)) { + EMSG(_(e_failed)); + } else { post_chdir(scope); - - /* Echo the new current directory if the command was typed. */ - if (KeyTyped || p_verbose >= 5) + // Echo the new current directory if the command was typed. + if (KeyTyped || p_verbose >= 5) { ex_pwd(eap); + } } + xfree(tofree); } } diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h index fb6aac223f..4def4cbbae 100644 --- a/src/nvim/ex_docmd.h +++ b/src/nvim/ex_docmd.h @@ -19,21 +19,6 @@ #define EXMODE_NORMAL 1 #define EXMODE_VIM 2 -/// The scope of a working-directory command like `:cd`. -/// -/// Scopes are enumerated from lowest to highest. When adding a scope make sure -/// to update all functions using scopes as well, such as the implementation of -/// `getcwd()`. When using scopes as limits (e.g. in loops) don't use the scopes -/// directly, use `MIN_CD_SCOPE` and `MAX_CD_SCOPE` instead. -typedef enum { - kCdScopeInvalid = -1, - kCdScopeWindow, ///< Affects one window. - kCdScopeTab, ///< Affects one tab page. - kCdScopeGlobal, ///< Affects the entire instance of Neovim. -} CdScope; -#define MIN_CD_SCOPE kCdScopeWindow -#define MAX_CD_SCOPE kCdScopeGlobal - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ex_docmd.h.generated.h" #endif diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 2ac8e27047..eb93921bb0 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -48,6 +48,7 @@ #include <limits.h> #include "nvim/vim.h" +#include "nvim/eval.h" #include "nvim/ascii.h" #include "nvim/file_search.h" #include "nvim/charset.h" @@ -1522,6 +1523,47 @@ theend: return file_name; } +static void do_autocmd_dirchanged(char_u *new_dir, CdScope scope) +{ + static bool recursive = false; + + if (recursive || !has_event(EVENT_DIRCHANGED)) { + // No autocommand was defined or we changed + // the directory from this autocommand. + return; + } + + recursive = true; + + dict_T *dict = get_vim_var_dict(VV_EVENT); + char buf[8]; + + switch (scope) { + case kCdScopeGlobal: + snprintf(buf, sizeof(buf), "global"); + break; + case kCdScopeTab: + snprintf(buf, sizeof(buf), "tab"); + break; + case kCdScopeWindow: + snprintf(buf, sizeof(buf), "window"); + break; + case kCdScopeInvalid: + // Should never happen. + assert(false); + } + + dict_add_nr_str(dict, "scope", 0L, (char_u *)buf); + dict_add_nr_str(dict, "cwd", 0L, new_dir); + dict_set_keys_readonly(dict); + + apply_autocmds(EVENT_DIRCHANGED, NULL, new_dir, false, NULL); + + dict_clear(dict); + + recursive = false; +} + /// Change to a file's directory. /// Caller must call shorten_fnames()! /// @return OK or FAIL @@ -1531,18 +1573,28 @@ int vim_chdirfile(char_u *fname) STRLCPY(dir, fname, MAXPATHL); *path_tail_with_sep(dir) = NUL; - return os_chdir((char *)dir) == 0 ? OK : FAIL; + if (os_chdir((char *)dir) != 0) { + return FAIL; + } + do_autocmd_dirchanged(dir, kCdScopeWindow); + + return OK; } /// Change directory to "new_dir". Search 'cdpath' for relative directory names. -int vim_chdir(char_u *new_dir) +int vim_chdir(char_u *new_dir, CdScope scope) { char_u *dir_name = find_directory_in_path(new_dir, STRLEN(new_dir), FNAME_MESS, curbuf->b_ffname); if (dir_name == NULL) { return -1; } + int r = os_chdir((char *)dir_name); + if (r == 0) { + do_autocmd_dirchanged(dir_name, scope); + } + xfree(dir_name); return r; } diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index a9f2d625cf..13329d771b 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -6765,8 +6765,9 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, fname = vim_strsave(fname); /* make a copy, so we can change it */ } else { sfname = vim_strsave(fname); - // don't try expanding the following events + // Don't try expanding the following events. if (event == EVENT_COLORSCHEME + || event == EVENT_DIRCHANGED || event == EVENT_FILETYPE || event == EVENT_FUNCUNDEFINED || event == EVENT_OPTIONSET @@ -6775,10 +6776,11 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, || event == EVENT_REMOTEREPLY || event == EVENT_SPELLFILEMISSING || event == EVENT_SYNTAX - || event == EVENT_TABCLOSED) + || event == EVENT_TABCLOSED) { fname = vim_strsave(fname); - else - fname = (char_u *)FullName_save((char *)fname, FALSE); + } else { + fname = (char_u *)FullName_save((char *)fname, false); + } } if (fname == NULL) { /* out of memory */ xfree(sfname); diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 463f4fcd8d..e3c84cb852 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -1249,4 +1249,20 @@ typedef enum { kBroken } WorkingStatus; +/// The scope of a working-directory command like `:cd`. +/// +/// Scopes are enumerated from lowest to highest. When adding a scope make sure +/// to update all functions using scopes as well, such as the implementation of +/// `getcwd()`. When using scopes as limits (e.g. in loops) don't use the scopes +/// directly, use `MIN_CD_SCOPE` and `MAX_CD_SCOPE` instead. +typedef enum { + kCdScopeInvalid = -1, + kCdScopeWindow, ///< Affects one window. + kCdScopeTab, ///< Affects one tab page. + kCdScopeGlobal, ///< Affects the entire instance of Neovim. +} CdScope; + +#define MIN_CD_SCOPE kCdScopeWindow +#define MAX_CD_SCOPE kCdScopeGlobal + #endif /* NVIM_GLOBALS_H */ diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 907353c271..10d6be85f8 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1404,7 +1404,7 @@ int op_delete(oparg_T *oap) if (oap->regname == 0) { set_clipboard(0, reg); - yank_do_autocmd(oap, reg); + do_autocmd_textyankpost(oap, reg); } } @@ -2315,7 +2315,7 @@ bool op_yank(oparg_T *oap, bool message) yankreg_T *reg = get_yank_register(oap->regname, YREG_YANK); op_yank_reg(oap, message, reg, is_append_register(oap->regname)); set_clipboard(oap->regname, reg); - yank_do_autocmd(oap, reg); + do_autocmd_textyankpost(oap, reg); return true; } @@ -2538,7 +2538,7 @@ static void yank_copy_line(yankreg_T *reg, struct block_def *bd, size_t y_idx) /// /// @param oap Operator arguments. /// @param reg The yank register used. -static void yank_do_autocmd(oparg_T *oap, yankreg_T *reg) +static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) FUNC_ATTR_NONNULL_ALL { static bool recursive = false; diff --git a/src/nvim/types.h b/src/nvim/types.h index 35a5d1e2bd..317bead3bb 100644 --- a/src/nvim/types.h +++ b/src/nvim/types.h @@ -14,4 +14,5 @@ typedef unsigned char char_u; typedef uint32_t u8char_T; typedef struct expand expand_T; + #endif // NVIM_TYPES_H |