diff options
-rw-r--r-- | src/nvim/autocmd.c | 4 | ||||
-rw-r--r-- | src/nvim/eval.c | 1 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 4 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 6 | ||||
-rw-r--r-- | src/nvim/globals.h | 2 | ||||
-rw-r--r-- | src/nvim/path.c | 10 | ||||
-rw-r--r-- | test/functional/api/autocmd_spec.lua | 28 |
7 files changed, 33 insertions, 22 deletions
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 53cca7baa1..427bce0e80 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -1603,6 +1603,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force // Save the autocmd_* variables and info about the current buffer. char *save_autocmd_fname = autocmd_fname; + bool save_autocmd_fname_full = autocmd_fname_full; int save_autocmd_bufnr = autocmd_bufnr; char *save_autocmd_match = autocmd_match; int save_autocmd_busy = autocmd_busy; @@ -1631,6 +1632,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force // Allocate MAXPATHL for when eval_vars() resolves the fullpath. autocmd_fname = xstrnsave(autocmd_fname, MAXPATHL); } + autocmd_fname_full = false; // call FullName_save() later // Set the buffer number to be used for <abuf>. autocmd_bufnr = buf == NULL ? 0 : buf->b_fnum; @@ -1674,6 +1676,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force || event == EVENT_USER || event == EVENT_WINCLOSED || event == EVENT_WINRESIZED || event == EVENT_WINSCROLLED) { fname = xstrdup(fname); + autocmd_fname_full = true; // don't expand it later } else { fname = FullName_save(fname, false); } @@ -1806,6 +1809,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force estack_pop(); xfree(autocmd_fname); autocmd_fname = save_autocmd_fname; + autocmd_fname_full = save_autocmd_fname_full; autocmd_bufnr = save_autocmd_bufnr; autocmd_match = save_autocmd_match; current_sctx = save_current_sctx; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 72005b1f35..ec5437a0b2 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -8609,6 +8609,7 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments, boo .es_entry = ((estack_T *)exestack.ga_data)[exestack.ga_len - 1], .autocmd_fname = autocmd_fname, .autocmd_match = autocmd_match, + .autocmd_fname_full = autocmd_fname_full, .autocmd_bufnr = autocmd_bufnr, .funccalp = (void *)get_current_funccal() }; diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index d465cade3e..788efe1e84 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -6552,6 +6552,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) sctx_T save_current_sctx; char *save_autocmd_fname, *save_autocmd_match; + bool save_autocmd_fname_full; int save_autocmd_bufnr; funccal_entry_T funccal_entry; @@ -6561,6 +6562,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) save_current_sctx = current_sctx; save_autocmd_fname = autocmd_fname; save_autocmd_match = autocmd_match; + save_autocmd_fname_full = autocmd_fname_full; save_autocmd_bufnr = autocmd_bufnr; save_funccal(&funccal_entry); @@ -6569,6 +6571,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) ((estack_T *)exestack.ga_data)[exestack.ga_len++] = provider_caller_scope.es_entry; autocmd_fname = provider_caller_scope.autocmd_fname; autocmd_match = provider_caller_scope.autocmd_match; + autocmd_fname_full = provider_caller_scope.autocmd_fname_full; autocmd_bufnr = provider_caller_scope.autocmd_bufnr; set_current_funccal((funccall_T *)(provider_caller_scope.funccalp)); } @@ -6586,6 +6589,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) exestack.ga_len--; autocmd_fname = save_autocmd_fname; autocmd_match = save_autocmd_match; + autocmd_fname_full = save_autocmd_fname_full; autocmd_bufnr = save_autocmd_bufnr; restore_funccal(); } diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 19ee1d841b..9ea9f28fa5 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6899,12 +6899,10 @@ char *eval_vars(char *src, const char *srcstart, size_t *usedlen, linenr_T *lnum break; case SPEC_AFILE: // file name for autocommand - if (autocmd_fname != NULL - && !path_is_absolute(autocmd_fname) - // For CmdlineEnter and related events, <afile> is not a path! #9348 - && !strequal("/", autocmd_fname)) { + if (autocmd_fname != NULL && !autocmd_fname_full) { // Still need to turn the fname into a full path. It was // postponed to avoid a delay when <afile> is not used. + autocmd_fname_full = true; result = FullName_save(autocmd_fname, false); // Copy into `autocmd_fname`, don't reassign it. #8165 xstrlcpy(autocmd_fname, result, MAXPATHL); diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 174dd6e13a..b71c0d2c70 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -336,6 +336,7 @@ EXTERN struct caller_scope { sctx_T script_ctx; estack_T es_entry; char *autocmd_fname, *autocmd_match; + bool autocmd_fname_full; int autocmd_bufnr; void *funccalp; } provider_caller_scope; @@ -759,6 +760,7 @@ EXTERN char *last_cmdline INIT(= NULL); // last command line (for ":) EXTERN char *repeat_cmdline INIT(= NULL); // command line for "." EXTERN char *new_last_cmdline INIT(= NULL); // new value for last_cmdline EXTERN char *autocmd_fname INIT(= NULL); // fname for <afile> on cmdline +EXTERN bool autocmd_fname_full INIT(= false); // autocmd_fname is full path EXTERN int autocmd_bufnr INIT(= 0); // fnum for <abuf> on cmdline EXTERN char *autocmd_match INIT(= NULL); // name for <amatch> on cmdline EXTERN bool did_cursorhold INIT(= false); // set when CursorHold t'gerd diff --git a/src/nvim/path.c b/src/nvim/path.c index 21a3a67e24..ea0d5a8be1 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -2087,17 +2087,17 @@ char *path_shorten_fname(char *full_path, char *dir_name) assert(dir_name != NULL); size_t len = strlen(dir_name); - // If dir_name is a path head, full_path can always be made relative. - if (len == (size_t)path_head_length() && is_path_head(dir_name)) { - return full_path + len; - } - // If full_path and dir_name do not match, it's impossible to make one // relative to the other. if (path_fnamencmp(dir_name, full_path, len) != 0) { return NULL; } + // If dir_name is a path head, full_path can always be made relative. + if (len == (size_t)path_head_length() && is_path_head(dir_name)) { + return full_path + len; + } + char *p = full_path + len; // If *p is not pointing to a path separator, this means that full_path's diff --git a/test/functional/api/autocmd_spec.lua b/test/functional/api/autocmd_spec.lua index 57390519de..4cfe8672b1 100644 --- a/test/functional/api/autocmd_spec.lua +++ b/test/functional/api/autocmd_spec.lua @@ -228,23 +228,28 @@ describe('autocmd api', function() end) it('receives an args table', function() - local res = exec_lua [[ - local group_id = vim.api.nvim_create_augroup("TestGroup", {}) - local autocmd_id = vim.api.nvim_create_autocmd("User", { + local group_id = meths.create_augroup("TestGroup", {}) + -- Having an existing autocmd calling expand("<afile>") shouldn't change args #18964 + meths.create_autocmd('User', { + group = 'TestGroup', + pattern = 'Te*', + command = 'call expand("<afile>")', + }) + + local autocmd_id = exec_lua [[ + return vim.api.nvim_create_autocmd("User", { group = "TestGroup", pattern = "Te*", callback = function(args) vim.g.autocmd_args = args end, }) - - return {group_id, autocmd_id} ]] meths.exec_autocmds("User", {pattern = "Test pattern"}) eq({ - id = res[2], - group = res[1], + id = autocmd_id, + group = group_id, event = "User", match = "Test pattern", file = "Test pattern", @@ -252,27 +257,24 @@ describe('autocmd api', function() }, meths.get_var("autocmd_args")) -- Test without a group - res = exec_lua [[ - local autocmd_id = vim.api.nvim_create_autocmd("User", { + autocmd_id = exec_lua [[ + return vim.api.nvim_create_autocmd("User", { pattern = "*", callback = function(args) vim.g.autocmd_args = args end, }) - - return {autocmd_id} ]] meths.exec_autocmds("User", {pattern = "some_pat"}) eq({ - id = res[1], + id = autocmd_id, group = nil, event = "User", match = "some_pat", file = "some_pat", buf = 1, }, meths.get_var("autocmd_args")) - end) it('can receive arbitrary data', function() |