mirror of https://github.com/folke/lazy.nvim.git
feat(build): build files and functions are now async. use coroutine.yield to interrupt and report progress
This commit is contained in:
parent
fcfd54835d
commit
368747bc9a
|
@ -183,12 +183,6 @@ M.defaults = {
|
|||
skip_if_doc_exists = true,
|
||||
},
|
||||
state = vim.fn.stdpath("state") .. "/lazy/state.json", -- state info for checker and other things
|
||||
build = {
|
||||
-- Plugins can provide a `build.lua` file that will be executed when the plugin is installed
|
||||
-- or updated. When the plugin spec also has a `build` command, the plugin's `build.lua` not be
|
||||
-- executed. In this case, a warning message will be shown.
|
||||
warn_on_override = true,
|
||||
},
|
||||
-- Enable profiling of lazy.nvim. This will add some overhead,
|
||||
-- so only enable this when you are debugging lazy.nvim
|
||||
profiling = {
|
||||
|
|
|
@ -74,6 +74,32 @@ function Task:start()
|
|||
self:_check()
|
||||
end
|
||||
|
||||
---@param fn async fun()
|
||||
function Task:async(fn)
|
||||
local co = coroutine.create(fn)
|
||||
local check = vim.uv.new_check()
|
||||
check:start(vim.schedule_wrap(function()
|
||||
local status = coroutine.status(co)
|
||||
if status == "dead" then
|
||||
check:stop()
|
||||
self:_check()
|
||||
elseif status == "suspended" then
|
||||
local ok, res = coroutine.resume(co)
|
||||
if not ok then
|
||||
error(res)
|
||||
elseif res then
|
||||
self.status = res
|
||||
self.output = self.output .. "\n" .. res
|
||||
vim.api.nvim_exec_autocmds("User", { pattern = "LazyRender", modeline = false })
|
||||
end
|
||||
end
|
||||
end))
|
||||
|
||||
table.insert(self._running, function()
|
||||
return check:is_active()
|
||||
end)
|
||||
end
|
||||
|
||||
---@private
|
||||
function Task:_check()
|
||||
for _, state in ipairs(self._running) do
|
||||
|
|
|
@ -8,25 +8,67 @@ local M = {}
|
|||
---@param plugin LazyPlugin
|
||||
local function get_build_file(plugin)
|
||||
for _, path in ipairs({ "build.lua", "build/init.lua" }) do
|
||||
path = plugin.dir .. "/" .. path
|
||||
if Util.file_exists(path) then
|
||||
if Util.file_exists(plugin.dir .. "/" .. path) then
|
||||
return path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local B = {}
|
||||
|
||||
---@param task LazyTask
|
||||
function B.rockspec(task)
|
||||
local root = Config.options.rocks.root .. "/" .. task.plugin.name
|
||||
vim.fn.mkdir(root, "p")
|
||||
task:spawn("luarocks", {
|
||||
args = {
|
||||
"--tree",
|
||||
root,
|
||||
"--server",
|
||||
Config.options.rocks.server,
|
||||
"--dev",
|
||||
"--lua-version",
|
||||
"5.1",
|
||||
"make",
|
||||
"--force-fast",
|
||||
},
|
||||
cwd = task.plugin.dir,
|
||||
})
|
||||
end
|
||||
|
||||
---@param task LazyTask
|
||||
---@param build string
|
||||
function B.cmd(task, build)
|
||||
local cmd = vim.api.nvim_parse_cmd(build:sub(2), {}) --[[@as vim.api.keyset.cmd]]
|
||||
task.output = vim.api.nvim_cmd(cmd, { output = true })
|
||||
end
|
||||
|
||||
---@param task LazyTask
|
||||
---@param build string
|
||||
function B.shell(task, build)
|
||||
local shell = vim.env.SHELL or vim.o.shell
|
||||
local shell_args = shell:find("cmd.exe", 1, true) and "/c" or "-c"
|
||||
|
||||
task:spawn(shell, {
|
||||
args = { shell_args, build },
|
||||
cwd = task.plugin.dir,
|
||||
})
|
||||
end
|
||||
|
||||
M.build = {
|
||||
---@param opts? {force:boolean}
|
||||
skip = function(plugin, opts)
|
||||
if opts and opts.force then
|
||||
return false
|
||||
end
|
||||
return not (plugin._.dirty and (plugin.build or get_build_file(plugin)))
|
||||
return not ((plugin._.dirty or plugin._.build) and (plugin.build or get_build_file(plugin)))
|
||||
end,
|
||||
run = function(self)
|
||||
vim.cmd([[silent! runtime plugin/rplugin.vim]])
|
||||
|
||||
Loader.load(self.plugin, { task = "build" })
|
||||
if self.plugin.build ~= "rockspec" then
|
||||
Loader.load(self.plugin, { task = "build" })
|
||||
end
|
||||
|
||||
local builders = self.plugin.build
|
||||
|
||||
|
@ -35,39 +77,29 @@ M.build = {
|
|||
return
|
||||
end
|
||||
|
||||
local build_file = get_build_file(self.plugin)
|
||||
if build_file then
|
||||
if builders then
|
||||
if Config.options.build.warn_on_override then
|
||||
Util.warn(
|
||||
("Plugin **%s** provides its own build script, but you also defined a `build` command.\nThe `build.lua` file will not be used"):format(
|
||||
self.plugin.name
|
||||
)
|
||||
)
|
||||
end
|
||||
else
|
||||
builders = function()
|
||||
Loader.source(build_file)
|
||||
end
|
||||
end
|
||||
end
|
||||
builders = builders or get_build_file(self.plugin)
|
||||
|
||||
if builders then
|
||||
builders = type(builders) == "table" and builders or { builders }
|
||||
---@cast builders (string|fun(LazyPlugin))[]
|
||||
for _, build in ipairs(builders) do
|
||||
if type(build) == "string" and build:sub(1, 1) == ":" then
|
||||
local cmd = vim.api.nvim_parse_cmd(build:sub(2), {})
|
||||
self.output = vim.api.nvim_cmd(cmd, { output = true })
|
||||
elseif type(build) == "function" then
|
||||
build(self.plugin)
|
||||
if type(build) == "function" then
|
||||
self:async(function()
|
||||
build(self.plugin)
|
||||
end)
|
||||
elseif build == "rockspec" then
|
||||
B.rockspec(self)
|
||||
elseif build:sub(1, 1) == ":" then
|
||||
B.cmd(self, build)
|
||||
elseif build:match("%.lua$") then
|
||||
local file = self.plugin.dir .. "/" .. build
|
||||
local chunk, err = loadfile(file)
|
||||
if not chunk or err then
|
||||
error(err)
|
||||
end
|
||||
self:async(chunk)
|
||||
else
|
||||
local shell = vim.env.SHELL or vim.o.shell
|
||||
local shell_args = shell:find("cmd.exe", 1, true) and "/c" or "-c"
|
||||
|
||||
self:spawn(shell, {
|
||||
args = { shell_args, build },
|
||||
cwd = self.plugin.dir,
|
||||
})
|
||||
B.shell(self, build)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -231,6 +231,18 @@ function M.markdown(msg, opts)
|
|||
)
|
||||
end
|
||||
|
||||
---@async
|
||||
---@param ms number
|
||||
function M.sleep(ms)
|
||||
local continue = false
|
||||
vim.defer_fn(function()
|
||||
continue = true
|
||||
end, ms)
|
||||
while not continue do
|
||||
coroutine.yield()
|
||||
end
|
||||
end
|
||||
|
||||
function M._dump(value, result)
|
||||
local t = type(value)
|
||||
if t == "number" or t == "boolean" then
|
||||
|
|
Loading…
Reference in New Issue