mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 10:45:16 -07:00
fix(events): don't expand args.file
for Lua callback (#31473)
Problem: In an autocommand Lua callback whether `args.file` is expanded depends on whether `expand('<afile>')` has been called. Solution: Always use the unexpanded file name for `args.file`. Related to #31306 and vim/vim#16106. This doesn't provide `sfname`, but at least makes `args.file` have a consistent value.
This commit is contained in:
parent
812d029702
commit
e9f4ceeb74
@ -3494,9 +3494,9 @@ nvim_create_autocmd({event}, {opts}) *nvim_create_autocmd()*
|
||||
• event: (string) name of the triggered event
|
||||
|autocmd-events|
|
||||
• group: (number|nil) autocommand group id, if any
|
||||
• match: (string) expanded value of <amatch>
|
||||
• buf: (number) expanded value of <abuf>
|
||||
• file: (string) expanded value of <afile>
|
||||
• file: (string) <afile> (not expanded to a full path)
|
||||
• match: (string) <amatch> (expanded to a full path)
|
||||
• buf: (number) <abuf>
|
||||
• data: (any) arbitrary data passed from
|
||||
|nvim_exec_autocmds()| *event-data*
|
||||
• command (string) optional: Vim command to execute on event.
|
||||
|
6
runtime/lua/vim/_meta/api.lua
generated
6
runtime/lua/vim/_meta/api.lua
generated
@ -963,9 +963,9 @@ function vim.api.nvim_create_augroup(name, opts) end
|
||||
--- - id: (number) autocommand id
|
||||
--- - event: (string) name of the triggered event `autocmd-events`
|
||||
--- - group: (number|nil) autocommand group id, if any
|
||||
--- - match: (string) expanded value of [<amatch>]
|
||||
--- - buf: (number) expanded value of [<abuf>]
|
||||
--- - file: (string) expanded value of [<afile>]
|
||||
--- - file: (string) [<afile>] (not expanded to a full path)
|
||||
--- - match: (string) [<amatch>] (expanded to a full path)
|
||||
--- - buf: (number) [<abuf>]
|
||||
--- - data: (any) arbitrary data passed from [nvim_exec_autocmds()] [event-data]()
|
||||
--- - command (string) optional: Vim command to execute on event. Cannot be used with
|
||||
--- {callback}
|
||||
|
@ -386,9 +386,9 @@ cleanup:
|
||||
/// - id: (number) autocommand id
|
||||
/// - event: (string) name of the triggered event |autocmd-events|
|
||||
/// - group: (number|nil) autocommand group id, if any
|
||||
/// - match: (string) expanded value of [<amatch>]
|
||||
/// - buf: (number) expanded value of [<abuf>]
|
||||
/// - file: (string) expanded value of [<afile>]
|
||||
/// - file: (string) [<afile>] (not expanded to a full path)
|
||||
/// - match: (string) [<amatch>] (expanded to a full path)
|
||||
/// - buf: (number) [<abuf>]
|
||||
/// - data: (any) arbitrary data passed from [nvim_exec_autocmds()] [event-data]()
|
||||
/// - command (string) optional: Vim command to execute on event. Cannot be used with
|
||||
/// {callback}
|
||||
|
@ -1666,7 +1666,9 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
||||
} else {
|
||||
autocmd_fname = fname_io;
|
||||
}
|
||||
char *afile_orig = NULL; ///< Unexpanded <afile>
|
||||
if (autocmd_fname != NULL) {
|
||||
afile_orig = xstrdup(autocmd_fname);
|
||||
// Allocate MAXPATHL for when eval_vars() resolves the fullpath.
|
||||
autocmd_fname = xstrnsave(autocmd_fname, MAXPATHL);
|
||||
}
|
||||
@ -1798,6 +1800,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
||||
// save vector size, to avoid an endless loop when more patterns
|
||||
// are added when executing autocommands
|
||||
.ausize = kv_size(autocmds[(int)event]),
|
||||
.afile_orig = afile_orig,
|
||||
.fname = fname,
|
||||
.sfname = sfname,
|
||||
.tail = tail,
|
||||
@ -1865,6 +1868,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
||||
autocmd_nested = save_autocmd_nested;
|
||||
xfree(SOURCING_NAME);
|
||||
estack_pop();
|
||||
xfree(afile_orig);
|
||||
xfree(autocmd_fname);
|
||||
autocmd_fname = save_autocmd_fname;
|
||||
autocmd_fname_full = save_autocmd_fname_full;
|
||||
@ -2029,8 +2033,8 @@ static bool call_autocmd_callback(const AutoCmd *ac, const AutoPatCmd *apc)
|
||||
MAXSIZE_TEMP_DICT(data, 7);
|
||||
PUT_C(data, "id", INTEGER_OBJ(ac->id));
|
||||
PUT_C(data, "event", CSTR_AS_OBJ(event_nr2name(apc->event)));
|
||||
PUT_C(data, "file", CSTR_AS_OBJ(apc->afile_orig));
|
||||
PUT_C(data, "match", CSTR_AS_OBJ(autocmd_match));
|
||||
PUT_C(data, "file", CSTR_AS_OBJ(autocmd_fname));
|
||||
PUT_C(data, "buf", INTEGER_OBJ(autocmd_bufnr));
|
||||
|
||||
if (apc->data) {
|
||||
|
@ -52,6 +52,7 @@ struct AutoPatCmd_S {
|
||||
AutoPat *lastpat; ///< Last matched AutoPat
|
||||
size_t auidx; ///< Current autocmd index to execute
|
||||
size_t ausize; ///< Saved AutoCmd vector size
|
||||
char *afile_orig; ///< Unexpanded <afile>
|
||||
char *fname; ///< Fname to match with
|
||||
char *sfname; ///< Sfname to match with
|
||||
char *tail; ///< Tail of fname
|
||||
|
@ -273,54 +273,72 @@ describe('autocmd api', function()
|
||||
eq({}, api.nvim_get_autocmds({ event = 'User', pattern = 'Test' }))
|
||||
end)
|
||||
|
||||
it('receives an args table', function()
|
||||
local function test_autocmd_args(event)
|
||||
local function get_amatch(pat)
|
||||
return event == 'User' and pat or vim.fs.normalize(n.fn.fnamemodify(pat, ':p'))
|
||||
end
|
||||
|
||||
local group_id = api.nvim_create_augroup('TestGroup', {})
|
||||
-- Having an existing autocmd calling expand("<afile>") shouldn't change args #18964
|
||||
api.nvim_create_autocmd('User', {
|
||||
api.nvim_create_autocmd(event, {
|
||||
group = 'TestGroup',
|
||||
pattern = 'Te*',
|
||||
command = 'call expand("<afile>")',
|
||||
})
|
||||
|
||||
local autocmd_id = exec_lua [[
|
||||
return vim.api.nvim_create_autocmd("User", {
|
||||
local autocmd_id = exec_lua(([[
|
||||
return vim.api.nvim_create_autocmd(%q, {
|
||||
group = "TestGroup",
|
||||
pattern = "Te*",
|
||||
callback = function(args)
|
||||
vim.g.autocmd_args = args
|
||||
end,
|
||||
})
|
||||
]]
|
||||
]]):format(event))
|
||||
|
||||
api.nvim_exec_autocmds('User', { pattern = 'Test pattern' })
|
||||
local exec_pat = 'Test pattern'
|
||||
local amatch = get_amatch(exec_pat)
|
||||
api.nvim_exec_autocmds(event, { pattern = exec_pat })
|
||||
eq({
|
||||
id = autocmd_id,
|
||||
group = group_id,
|
||||
event = 'User',
|
||||
match = 'Test pattern',
|
||||
file = 'Test pattern',
|
||||
event = event,
|
||||
match = amatch,
|
||||
file = exec_pat,
|
||||
buf = 1,
|
||||
}, api.nvim_get_var('autocmd_args'))
|
||||
|
||||
-- Test without a group
|
||||
autocmd_id = exec_lua [[
|
||||
return vim.api.nvim_create_autocmd("User", {
|
||||
autocmd_id = exec_lua(([[
|
||||
return vim.api.nvim_create_autocmd(%q, {
|
||||
pattern = "*",
|
||||
callback = function(args)
|
||||
vim.g.autocmd_args = args
|
||||
end,
|
||||
})
|
||||
]]
|
||||
]]):format(event))
|
||||
|
||||
api.nvim_exec_autocmds('User', { pattern = 'some_pat' })
|
||||
exec_pat = 'some_pat'
|
||||
amatch = get_amatch(exec_pat)
|
||||
api.nvim_exec_autocmds(event, { pattern = exec_pat })
|
||||
eq({
|
||||
id = autocmd_id,
|
||||
group = nil,
|
||||
event = 'User',
|
||||
match = 'some_pat',
|
||||
file = 'some_pat',
|
||||
event = event,
|
||||
match = amatch,
|
||||
file = exec_pat,
|
||||
buf = 1,
|
||||
}, api.nvim_get_var('autocmd_args'))
|
||||
end
|
||||
|
||||
describe('receives correct args table', function()
|
||||
it('for event that takes non-file pattern', function()
|
||||
test_autocmd_args('User')
|
||||
end)
|
||||
|
||||
it('for event that takes file pattern', function()
|
||||
test_autocmd_args('BufEnter')
|
||||
end)
|
||||
end)
|
||||
|
||||
it('can receive arbitrary data', function()
|
||||
|
Loading…
Reference in New Issue
Block a user