Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions lua/zpack/lazy_trigger/event.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local util = require('zpack.utils')
local state = require('zpack.state')
local loader = require('zpack.plugin_loader')
local refire = require('zpack.lazy_trigger.refire')

local M = {}

Expand Down Expand Up @@ -83,8 +84,15 @@ M.setup = function(pack_spec, spec, event)

if #other_events > 0 then
util.autocmd(other_events, function(ev)
loader.process_spec(pack_spec)
vim.api.nvim_exec_autocmds(ev.event, { buffer = ev.buf, modeline = false })
local snap = refire.snapshot(ev.event)
local ok, err = pcall(loader.process_spec, pack_spec)
if not ok then
vim.schedule(function()
vim.notify(("Failed to load plugin: %s"):format(err), vim.log.levels.ERROR)
end)
return
end
refire.exec(ev.event, ev.buf, ev.data, snap)
end, { group = state.lazy_group, once = true, pattern = normalized_event.pattern })
end
end
Expand Down
22 changes: 10 additions & 12 deletions lua/zpack/lazy_trigger/ft.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local util = require('zpack.utils')
local state = require('zpack.state')
local loader = require('zpack.plugin_loader')
local refire = require('zpack.lazy_trigger.refire')

local M = {}

Expand All @@ -10,18 +11,15 @@ M.setup = function(pack_spec, ft)
local filetypes = util.normalize_string_list(ft)

util.autocmd("FileType", function(ev)
loader.process_spec(pack_spec)

-- Re-trigger events for the buffer that triggered loading to ensure LSP/Treesitter attach
vim.schedule(function()
local bufnr = ev.buf
if not vim.api.nvim_buf_is_valid(bufnr) then
return
end
vim.api.nvim_exec_autocmds("BufReadPre", { buffer = bufnr, modeline = false })
vim.api.nvim_exec_autocmds("BufReadPost", { buffer = bufnr, modeline = false })
vim.api.nvim_exec_autocmds("FileType", { buffer = bufnr, modeline = false })
end)
local snap = refire.snapshot("FileType")
local ok, err = pcall(loader.process_spec, pack_spec)
if not ok then
vim.schedule(function()
vim.notify(("Failed to load plugin: %s"):format(err), vim.log.levels.ERROR)
end)
return
end
refire.exec("FileType", ev.buf, ev.data, snap)
end, { group = state.lazy_group, pattern = filetypes, once = true })
end

Expand Down
89 changes: 89 additions & 0 deletions lua/zpack/lazy_trigger/refire.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
local M = {}

local triggers = {
FileType = "BufReadPost",
BufReadPost = "BufReadPre",
}

---@param event string
---@return string[]
local function build_chain(event)
local chain = {}
local current = event
while current do
table.insert(chain, 1, current)
current = triggers[current]
end
return chain
end

---@param event string
---@return table<string, table<number, boolean>?>
M.snapshot = function(event)
local chain = build_chain(event)
local snap = {}
for _, ev in ipairs(chain) do
if ev == "FileType" then
snap[ev] = nil
else
local existing = {}
for _, au in ipairs(vim.api.nvim_get_autocmds({ event = ev })) do
if au.group then
existing[au.group] = true
end
end
snap[ev] = existing
end
end
return snap
end

---@param ev string
---@param buf number
---@param ev_data? any
---@param snap table<string, table<number, boolean>?>
local function fire_new_groups(ev, buf, ev_data, snap)
local pre_existing = snap[ev]
if pre_existing == nil then
pcall(vim.api.nvim_exec_autocmds, ev, {
buffer = buf,
data = ev_data,
modeline = false,
})
return
end

local fired = {}
for _, au in ipairs(vim.api.nvim_get_autocmds({ event = ev })) do
if au.group and not pre_existing[au.group] and not fired[au.group] then
fired[au.group] = true
pcall(vim.api.nvim_exec_autocmds, ev, {
buffer = buf,
group = au.group_name,
data = ev_data,
modeline = false,
})
end
end
end

---@param event string
---@param buf number
---@param data? any
---@param snapshot table<string, table<number, boolean>?>
M.exec = function(event, buf, data, snapshot)
if not vim.api.nvim_buf_is_valid(buf) then
return
end

local chain = build_chain(event)

for _, ev in ipairs(chain) do
if not vim.api.nvim_buf_is_valid(buf) then
return
end
fire_new_groups(ev, buf, ev == event and data or nil, snapshot)
end
end

return M
1 change: 1 addition & 0 deletions tests/helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ function M.cleanup_test_env()
package.loaded['zpack.plugin_loader'] = nil
package.loaded['zpack.lazy_trigger.event'] = nil
package.loaded['zpack.lazy_trigger.ft'] = nil
package.loaded['zpack.lazy_trigger.refire'] = nil
package.loaded['zpack.lazy_trigger.cmd'] = nil
package.loaded['zpack.lazy_trigger.keys'] = nil
package.loaded['zpack.keymap'] = nil
Expand Down
Loading
Loading