fix(pack): install missing plugins asynchronously without startup updates
This commit is contained in:
@@ -1,16 +1,39 @@
|
|||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
function M.setup()
|
function M.setup()
|
||||||
local ok_configs, ts_configs = pcall(require, "nvim-treesitter.configs")
|
local ok_ts, ts = pcall(require, "nvim-treesitter")
|
||||||
if not ok_configs then
|
if not ok_ts then
|
||||||
vim.schedule(function()
|
vim.schedule(function()
|
||||||
vim.notify("nvim-treesitter is not available yet. Run :lua vim.pack.update() and restart.",
|
vim.notify("nvim-treesitter is not ready yet. Wait for background plugin install and restart Neovim.",
|
||||||
vim.log.levels.WARN)
|
vim.log.levels.WARN)
|
||||||
end)
|
end)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
ts_configs.setup({
|
local move_config = {
|
||||||
|
goto_next_start = {
|
||||||
|
["]f"] = "@function.outer",
|
||||||
|
["]c"] = "@class.outer",
|
||||||
|
["]a"] = "@parameter.inner",
|
||||||
|
},
|
||||||
|
goto_next_end = {
|
||||||
|
["]F"] = "@function.outer",
|
||||||
|
["]C"] = "@class.outer",
|
||||||
|
["]A"] = "@parameter.inner",
|
||||||
|
},
|
||||||
|
goto_previous_start = {
|
||||||
|
["[f"] = "@function.outer",
|
||||||
|
["[c"] = "@class.outer",
|
||||||
|
["[a"] = "@parameter.inner",
|
||||||
|
},
|
||||||
|
goto_previous_end = {
|
||||||
|
["[F"] = "@function.outer",
|
||||||
|
["[C"] = "@class.outer",
|
||||||
|
["[A"] = "@parameter.inner",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
ts.setup({
|
||||||
ensure_installed = {
|
ensure_installed = {
|
||||||
"bash",
|
"bash",
|
||||||
"c",
|
"c",
|
||||||
@@ -51,26 +74,10 @@ function M.setup()
|
|||||||
textobjects = {
|
textobjects = {
|
||||||
move = {
|
move = {
|
||||||
enable = true,
|
enable = true,
|
||||||
goto_next_start = {
|
goto_next_start = move_config.goto_next_start,
|
||||||
["]f"] = "@function.outer",
|
goto_next_end = move_config.goto_next_end,
|
||||||
["]c"] = "@class.outer",
|
goto_previous_start = move_config.goto_previous_start,
|
||||||
["]a"] = "@parameter.inner",
|
goto_previous_end = move_config.goto_previous_end,
|
||||||
},
|
|
||||||
goto_next_end = {
|
|
||||||
["]F"] = "@function.outer",
|
|
||||||
["]C"] = "@class.outer",
|
|
||||||
["]A"] = "@parameter.inner",
|
|
||||||
},
|
|
||||||
goto_previous_start = {
|
|
||||||
["[f"] = "@function.outer",
|
|
||||||
["[c"] = "@class.outer",
|
|
||||||
["[a"] = "@parameter.inner",
|
|
||||||
},
|
|
||||||
goto_previous_end = {
|
|
||||||
["[F"] = "@function.outer",
|
|
||||||
["[C"] = "@class.outer",
|
|
||||||
["[A"] = "@parameter.inner",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -84,7 +91,7 @@ function M.setup()
|
|||||||
if name:find("goto") == 1 then
|
if name:find("goto") == 1 then
|
||||||
move[name] = function(query, ...)
|
move[name] = function(query, ...)
|
||||||
if vim.wo.diff then
|
if vim.wo.diff then
|
||||||
local config = ts_configs.get_module("textobjects.move")[name]
|
local config = move_config[name]
|
||||||
for key, textobject in pairs(config or {}) do
|
for key, textobject in pairs(config or {}) do
|
||||||
if query == textobject and key:find("[%]%[][cC]") then
|
if query == textobject and key:find("[%]%[][cC]") then
|
||||||
vim.cmd("normal! " .. key)
|
vim.cmd("normal! " .. key)
|
||||||
|
|||||||
+68
-3
@@ -1,4 +1,5 @@
|
|||||||
local M = {}
|
local M = {}
|
||||||
|
local async_install_started = false
|
||||||
|
|
||||||
local function has_valid_head(path)
|
local function has_valid_head(path)
|
||||||
if vim.fn.isdirectory(path .. "/.git") == 0 then
|
if vim.fn.isdirectory(path .. "/.git") == 0 then
|
||||||
@@ -31,6 +32,45 @@ local function to_src(value)
|
|||||||
return "https://github.com/" .. value
|
return "https://github.com/" .. value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function plugin_name(spec)
|
||||||
|
if type(spec) == "table" and type(spec.name) == "string" and spec.name ~= "" then
|
||||||
|
return spec.name
|
||||||
|
end
|
||||||
|
|
||||||
|
local src = type(spec) == "string" and spec or spec.src
|
||||||
|
local name = src:gsub("/$", ""):match("([^/]+)$") or src
|
||||||
|
return name:gsub("%.git$", "")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function plugin_installed(spec)
|
||||||
|
local root = vim.fn.stdpath("data") .. "/site/pack/core/opt"
|
||||||
|
local path = root .. "/" .. plugin_name(spec)
|
||||||
|
return vim.fn.isdirectory(path) == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local function install_missing_async(specs)
|
||||||
|
if async_install_started or #specs == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
async_install_started = true
|
||||||
|
|
||||||
|
local specs_json = vim.json.encode(specs)
|
||||||
|
local lua_expr = string.format(
|
||||||
|
"local s=vim.json.decode(%q); vim.pack.add(s,{confirm=false,load=false})",
|
||||||
|
specs_json
|
||||||
|
)
|
||||||
|
|
||||||
|
vim.system({
|
||||||
|
vim.v.progpath,
|
||||||
|
"--headless",
|
||||||
|
"-u",
|
||||||
|
"NONE",
|
||||||
|
"+lua " .. lua_expr,
|
||||||
|
"+qall",
|
||||||
|
}, { detach = true })
|
||||||
|
end
|
||||||
|
|
||||||
function M.add(specs)
|
function M.add(specs)
|
||||||
local resolved = {}
|
local resolved = {}
|
||||||
|
|
||||||
@@ -44,17 +84,42 @@ function M.add(specs)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local ok, err = pcall(vim.pack.add, resolved, { confirm = false, load = true })
|
local installed = {}
|
||||||
|
local missing = {}
|
||||||
|
|
||||||
|
for _, spec in ipairs(resolved) do
|
||||||
|
if plugin_installed(spec) then
|
||||||
|
table.insert(installed, spec)
|
||||||
|
else
|
||||||
|
table.insert(missing, spec)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if #missing > 0 then
|
||||||
|
install_missing_async(missing)
|
||||||
|
vim.schedule(function()
|
||||||
|
vim.notify(
|
||||||
|
"Missing plugins detected. Started background install; restart Neovim when it finishes.",
|
||||||
|
vim.log.levels.WARN
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
if #installed == 0 then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok, err = pcall(vim.pack.add, installed, { confirm = false, load = true })
|
||||||
|
|
||||||
if not ok and tostring(err):find("ambiguous argument 'HEAD'", 1, true) then
|
if not ok and tostring(err):find("ambiguous argument 'HEAD'", 1, true) then
|
||||||
prune_broken_pack_repos()
|
prune_broken_pack_repos()
|
||||||
vim.fn.delete(vim.fn.stdpath("config") .. "/nvim-pack-lock.json")
|
vim.fn.delete(vim.fn.stdpath("config") .. "/nvim-pack-lock.json")
|
||||||
ok, err = pcall(vim.pack.add, resolved, { confirm = false, load = true })
|
ok, err = pcall(vim.pack.add, installed, { confirm = false, load = true })
|
||||||
end
|
end
|
||||||
|
|
||||||
if not ok then
|
if not ok then
|
||||||
vim.schedule(function()
|
vim.schedule(function()
|
||||||
local msg = "vim.pack failed to install/load plugins. Check network and run :lua vim.pack.update()."
|
local msg = "vim.pack failed to load installed plugins."
|
||||||
vim.notify(msg .. "\n" .. tostring(err), vim.log.levels.WARN)
|
vim.notify(msg .. "\n" .. tostring(err), vim.log.levels.WARN)
|
||||||
end)
|
end)
|
||||||
return false
|
return false
|
||||||
|
|||||||
Reference in New Issue
Block a user