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
73ea05feda
commit
97704cf48a
|
@ -183,12 +183,6 @@ M.defaults = {
|
||||||
skip_if_doc_exists = true,
|
skip_if_doc_exists = true,
|
||||||
},
|
},
|
||||||
state = vim.fn.stdpath("state") .. "/lazy/state.json", -- state info for checker and other things
|
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,
|
-- Enable profiling of lazy.nvim. This will add some overhead,
|
||||||
-- so only enable this when you are debugging lazy.nvim
|
-- so only enable this when you are debugging lazy.nvim
|
||||||
profiling = {
|
profiling = {
|
||||||
|
|
|
@ -74,6 +74,32 @@ function Task:start()
|
||||||
self:_check()
|
self:_check()
|
||||||
end
|
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
|
---@private
|
||||||
function Task:_check()
|
function Task:_check()
|
||||||
for _, state in ipairs(self._running) do
|
for _, state in ipairs(self._running) do
|
||||||
|
|
|
@ -8,25 +8,67 @@ local M = {}
|
||||||
---@param plugin LazyPlugin
|
---@param plugin LazyPlugin
|
||||||
local function get_build_file(plugin)
|
local function get_build_file(plugin)
|
||||||
for _, path in ipairs({ "build.lua", "build/init.lua" }) do
|
for _, path in ipairs({ "build.lua", "build/init.lua" }) do
|
||||||
path = plugin.dir .. "/" .. path
|
if Util.file_exists(plugin.dir .. "/" .. path) then
|
||||||
if Util.file_exists(path) then
|
|
||||||
return path
|
return path
|
||||||
end
|
end
|
||||||
end
|
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 = {
|
M.build = {
|
||||||
---@param opts? {force:boolean}
|
---@param opts? {force:boolean}
|
||||||
skip = function(plugin, opts)
|
skip = function(plugin, opts)
|
||||||
if opts and opts.force then
|
if opts and opts.force then
|
||||||
return false
|
return false
|
||||||
end
|
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,
|
end,
|
||||||
run = function(self)
|
run = function(self)
|
||||||
vim.cmd([[silent! runtime plugin/rplugin.vim]])
|
vim.cmd([[silent! runtime plugin/rplugin.vim]])
|
||||||
|
|
||||||
|
if self.plugin.build ~= "rockspec" then
|
||||||
Loader.load(self.plugin, { task = "build" })
|
Loader.load(self.plugin, { task = "build" })
|
||||||
|
end
|
||||||
|
|
||||||
local builders = self.plugin.build
|
local builders = self.plugin.build
|
||||||
|
|
||||||
|
@ -35,39 +77,29 @@ M.build = {
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local build_file = get_build_file(self.plugin)
|
builders = builders or 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
|
|
||||||
if builders then
|
if builders then
|
||||||
builders = type(builders) == "table" and builders or { builders }
|
builders = type(builders) == "table" and builders or { builders }
|
||||||
---@cast builders (string|fun(LazyPlugin))[]
|
---@cast builders (string|fun(LazyPlugin))[]
|
||||||
for _, build in ipairs(builders) do
|
for _, build in ipairs(builders) do
|
||||||
if type(build) == "string" and build:sub(1, 1) == ":" then
|
if type(build) == "function" then
|
||||||
local cmd = vim.api.nvim_parse_cmd(build:sub(2), {})
|
self:async(function()
|
||||||
self.output = vim.api.nvim_cmd(cmd, { output = true })
|
|
||||||
elseif type(build) == "function" then
|
|
||||||
build(self.plugin)
|
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
|
else
|
||||||
local shell = vim.env.SHELL or vim.o.shell
|
B.shell(self, build)
|
||||||
local shell_args = shell:find("cmd.exe", 1, true) and "/c" or "-c"
|
|
||||||
|
|
||||||
self:spawn(shell, {
|
|
||||||
args = { shell_args, build },
|
|
||||||
cwd = self.plugin.dir,
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -231,6 +231,18 @@ function M.markdown(msg, opts)
|
||||||
)
|
)
|
||||||
end
|
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)
|
function M._dump(value, result)
|
||||||
local t = type(value)
|
local t = type(value)
|
||||||
if t == "number" or t == "boolean" then
|
if t == "number" or t == "boolean" then
|
||||||
|
|
Loading…
Reference in New Issue