aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarco Hinz <mh.codebro@gmail.com>2017-01-16 13:36:16 +0100
committerGitHub <noreply@github.com>2017-01-16 13:36:16 +0100
commit340f79b4b8f1021f4a3b88265ced2ce39d0e2e03 (patch)
tree71509fab0581f8454272493e38fd0018a32c3c5f /src
parentfa94c4c2d917b70df443ba0ebcd87da35dc1bb30 (diff)
parent1f7a119f5efc13fbce6446bf268c2e0f9d753147 (diff)
downloadrneovim-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.c2
-rw-r--r--src/nvim/auevents.lua2
-rw-r--r--src/nvim/ex_docmd.c41
-rw-r--r--src/nvim/ex_docmd.h15
-rw-r--r--src/nvim/file_search.c56
-rw-r--r--src/nvim/fileio.c10
-rw-r--r--src/nvim/globals.h16
-rw-r--r--src/nvim/ops.c6
-rw-r--r--src/nvim/types.h1
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