From 70f91956e7f03e740b51cbc14c87df6a6f74538f Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Tue, 10 Oct 2023 21:51:09 +0200 Subject: [PATCH] perf(plugin): move all lazy.nvim related code to `lazyvim.util.plugin` --- lua/lazyvim/config/init.lua | 202 +++++------------------------------ lua/lazyvim/plugins/init.lua | 10 ++ lua/lazyvim/util/init.lua | 1 + lua/lazyvim/util/plugin.lua | 148 +++++++++++++++++++++++++ 4 files changed, 183 insertions(+), 178 deletions(-) create mode 100644 lua/lazyvim/util/plugin.lua diff --git a/lua/lazyvim/config/init.lua b/lua/lazyvim/config/init.lua index 23ca90d4..201629fa 100644 --- a/lua/lazyvim/config/init.lua +++ b/lua/lazyvim/config/init.lua @@ -3,10 +3,6 @@ local Util = require("lazyvim.util") ---@class LazyVimConfig: LazyVimOptions local M = {} -M.lazy_version = ">=10.8.0" -M.use_lazy_file = true -M.lazy_file_events = { "BufReadPost", "BufNewFile", "BufWritePre" } - ---@class LazyVimOptions local defaults = { -- colorscheme can be a string like `catppuccin` or a function that will load the colorscheme @@ -85,61 +81,13 @@ local defaults = { }, } -M.renames = { - ["windwp/nvim-spectre"] = "nvim-pack/nvim-spectre", - ["jose-elias-alvarez/null-ls.nvim"] = "nvimtools/none-ls.nvim", - ["null-ls.nvim"] = "none-ls.nvim", -} - ---@type LazyVimOptions local options ----@param lines {[1]:string, [2]:string}[] -function M.msg(lines) - vim.cmd([[clear]]) - vim.api.nvim_echo(lines, true, {}) - vim.fn.getchar() -end - ---@param opts? LazyVimOptions function M.setup(opts) options = vim.tbl_deep_extend("force", defaults, opts or {}) or {} - if vim.fn.has("nvim-0.9.0") == 0 then - M.msg({ - { - "LazyVim requires Neovim >= 0.9.0\n", - "ErrorMsg", - }, - { "Press any key to exit", "MoreMsg" }, - }) - vim.cmd([[quit]]) - return - end - - if not M.has() then - M.msg({ - { - "LazyVim requires lazy.nvim " .. M.lazy_version .. "\n", - "WarningMsg", - }, - { "Press any key to attempt an upgrade", "MoreMsg" }, - }) - - vim.api.nvim_create_autocmd("User", { - pattern = "LazyVimStarted", - callback = function() - require("lazy").update({ plugins = { "lazy.nvim" }, wait = true }) - M.msg({ - { - "**lazy.nvim** has been upgraded.\nPlease restart **Neovim**", - "WarningMsg", - }, - }) - end, - }) - end - -- autocmds can be loaded lazily when not opening a file local lazy_autocmds = vim.fn.argc(-1) == 0 if not lazy_autocmds then @@ -159,10 +107,6 @@ function M.setup(opts) end, }) - if M.use_lazy_file then - M.lazy_file() - end - Util.track("colorscheme") Util.try(function() if type(M.colorscheme) == "function" then @@ -180,64 +124,6 @@ function M.setup(opts) Util.track() end --- Properly load file based plugins without blocking the UI -function M.lazy_file() - local events = {} ---@type {event: string, buf: number, data?: any}[] - - local function load() - if #events == 0 then - return - end - local Event = require("lazy.core.handler.event") - vim.api.nvim_del_augroup_by_name("lazy_file") - - Util.track({ event = "LazyVim.lazy_file" }) - - ---@type table - local skips = {} - for _, event in ipairs(events) do - skips[event.event] = skips[event.event] or Event.get_augroups(event.event) - end - - vim.api.nvim_exec_autocmds("User", { pattern = "LazyFile", modeline = false }) - for _, event in ipairs(events) do - Event.trigger({ - event = event.event, - exclude = skips[event.event], - data = event.data, - buf = event.buf, - }) - if vim.bo[event.buf].filetype then - Event.trigger({ - event = "FileType", - buf = event.buf, - }) - end - end - vim.api.nvim_exec_autocmds("CursorMoved", { modeline = false }) - events = {} - Util.track() - end - - -- schedule wrap so that nested autocmds are executed - -- and the UI can continue rendering without blocking - load = vim.schedule_wrap(load) - - vim.api.nvim_create_autocmd(M.lazy_file_events, { - group = vim.api.nvim_create_augroup("lazy_file", { clear = true }), - callback = function(event) - table.insert(events, event) - load() - end, - }) -end - ----@param range? string -function M.has(range) - local Semver = require("lazy.manage.semver") - return Semver.range(range or M.lazy_version):matches(require("lazy.core.config").version or "0.0.0") -end - ---@param name "autocmds" | "options" | "keymaps" function M.load(name) local function _load(mod) @@ -262,71 +148,31 @@ end M.did_init = false function M.init() - if not M.did_init then - M.did_init = true - local plugin = require("lazy.core.config").spec.plugins.LazyVim - if plugin then - vim.opt.rtp:append(plugin.dir) - end - - package.preload["lazyvim.plugins.lsp.format"] = function() - Util.deprecate([[require("lazyvim.plugins.lsp.format")]], [[require("lazyvim.util").format]]) - return Util.format - end - - M.use_lazy_file = M.use_lazy_file and vim.fn.argc(-1) > 0 - ---@diagnostic disable-next-line: undefined-field - M.use_lazy_file = M.use_lazy_file and require("lazy.core.handler.event").trigger_events == nil - - -- delay notifications till vim.notify was replaced or after 500ms - require("lazyvim.util").lazy_notify() - - -- load options here, before lazy init while sourcing plugin modules - -- this is needed to make sure options will be correctly applied - -- after installing missing plugins - M.load("options") - local Plugin = require("lazy.core.plugin") - local add = Plugin.Spec.add - ---@diagnostic disable-next-line: duplicate-set-field - Plugin.Spec.add = function(self, plugin, ...) - if type(plugin) == "table" then - if M.renames[plugin[1]] then - Util.warn( - ("Plugin `%s` was renamed to `%s`.\nPlease update your config for `%s`"):format( - plugin[1], - M.renames[plugin[1]], - self.importing or "LazyVim" - ), - { title = "LazyVim" } - ) - plugin[1] = M.renames[plugin[1]] - end - if not M.use_lazy_file and plugin.event then - if plugin.event == "LazyFile" then - plugin.event = M.lazy_file_events - elseif type(plugin.event) == "table" then - local events = {} ---@type string[] - for _, event in ipairs(plugin.event) do - if event == "LazyFile" then - vim.list_extend(events, M.lazy_file_events) - else - events[#events + 1] = event - end - end - end - end - end - return add(self, plugin, ...) - end - - -- Add support for the LazyFile event - local Event = require("lazy.core.handler.event") - local _event = Event._event - ---@diagnostic disable-next-line: duplicate-set-field - Event._event = function(self, value) - return value == "LazyFile" and "User LazyFile" or _event(self, value) - end + if M.did_init then + return end + M.did_init = true + local plugin = require("lazy.core.config").spec.plugins.LazyVim + if plugin then + vim.opt.rtp:append(plugin.dir) + end + + package.preload["lazyvim.plugins.lsp.format"] = function() + Util.deprecate([[require("lazyvim.plugins.lsp.format")]], [[require("lazyvim.util").format]]) + return Util.format + end + + -- delay notifications till vim.notify was replaced or after 500ms + require("lazyvim.util").lazy_notify() + + -- load options here, before lazy init while sourcing plugin modules + -- this is needed to make sure options will be correctly applied + -- after installing missing plugins + M.load("options") + + Util.plugin.fix_imports() + Util.plugin.fix_renames() + Util.plugin.lazy_file() end setmetatable(M, { diff --git a/lua/lazyvim/plugins/init.lua b/lua/lazyvim/plugins/init.lua index 847d8470..8c7b5fa1 100644 --- a/lua/lazyvim/plugins/init.lua +++ b/lua/lazyvim/plugins/init.lua @@ -1,3 +1,13 @@ +if vim.fn.has("nvim-0.9.0") == 0 then + vim.api.nvim_echo({ + { "LazyVim requires Neovim >= 0.9.0\n", "ErrorMsg" }, + { "Press any key to exit", "MoreMsg" }, + }, true, {}) + vim.fn.getchar() + vim.cmd([[quit]]) + return {} +end + require("lazyvim.config").init() return { diff --git a/lua/lazyvim/util/init.lua b/lua/lazyvim/util/init.lua index 146e73e2..c46ac22e 100644 --- a/lua/lazyvim/util/init.lua +++ b/lua/lazyvim/util/init.lua @@ -8,6 +8,7 @@ local LazyUtil = require("lazy.core.util") ---@field terminal lazyvim.util.terminal ---@field toggle lazyvim.util.toggle ---@field format lazyvim.util.format +---@field plugin lazyvim.util.plugin local M = {} ---@type table diff --git a/lua/lazyvim/util/plugin.lua b/lua/lazyvim/util/plugin.lua new file mode 100644 index 00000000..a9d6ccd2 --- /dev/null +++ b/lua/lazyvim/util/plugin.lua @@ -0,0 +1,148 @@ +local Plugin = require("lazy.core.plugin") +local Util = require("lazyvim.util") + +---@class lazyvim.util.plugin +local M = {} + +M.use_lazy_file = true +M.lazy_file_events = { "BufReadPost", "BufNewFile", "BufWritePre" } + +---@type table +M.deprecated_extras = { + ["lazyvim.plugins.extras.formatting.conform"] = "`conform.nvim` is now the default **LazyVim** formatter.", + ["lazyvim.plugins.extras.linting.nvim-lint"] = "`nvim-lint` is now the default **LazyVim** linter.", +} + +---@type table +M.renames = { + ["windwp/nvim-spectre"] = "nvim-pack/nvim-spectre", + ["jose-elias-alvarez/null-ls.nvim"] = "nvimtools/none-ls.nvim", + ["null-ls.nvim"] = "none-ls.nvim", +} + +-- Properly load file based plugins without blocking the UI +function M.lazy_file() + M.use_lazy_file = M.use_lazy_file and vim.fn.argc(-1) > 0 + ---@diagnostic disable-next-line: undefined-field + M.use_lazy_file = M.use_lazy_file and require("lazy.core.handler.event").trigger_events == nil + M.use_lazy_file = false + + M.fix_lazy_file() + + if not M.use_lazy_file then + return + end + + local events = {} ---@type {event: string, buf: number, data?: any}[] + + local function load() + if #events == 0 then + return + end + local Event = require("lazy.core.handler.event") + vim.api.nvim_del_augroup_by_name("lazy_file") + + Util.track({ event = "LazyVim.lazy_file" }) + + ---@type table + local skips = {} + for _, event in ipairs(events) do + skips[event.event] = skips[event.event] or Event.get_augroups(event.event) + end + + vim.api.nvim_exec_autocmds("User", { pattern = "LazyFile", modeline = false }) + for _, event in ipairs(events) do + Event.trigger({ + event = event.event, + exclude = skips[event.event], + data = event.data, + buf = event.buf, + }) + if vim.bo[event.buf].filetype then + Event.trigger({ + event = "FileType", + buf = event.buf, + }) + end + end + vim.api.nvim_exec_autocmds("CursorMoved", { modeline = false }) + events = {} + Util.track() + end + + -- schedule wrap so that nested autocmds are executed + -- and the UI can continue rendering without blocking + load = vim.schedule_wrap(load) + + vim.api.nvim_create_autocmd(M.lazy_file_events, { + group = vim.api.nvim_create_augroup("lazy_file", { clear = true }), + callback = function(event) + table.insert(events, event) + load() + end, + }) +end + +function M.fix_imports() + local import = Plugin.Spec.import + ---@diagnostic disable-next-line: duplicate-set-field + function Plugin.Spec:import(spec) + local dep = M.deprecated_extras[spec and spec.import] + if dep then + dep = dep .. "\n" .. "Please remove the extra to hide this warning." + Util.warn(dep, { title = "LazyVim", once = true, stacktrace = true, stacklevel = 6 }) + return + end + return import(self, spec) + end +end + +function M.fix_renames() + local add = Plugin.Spec.add + ---@diagnostic disable-next-line: duplicate-set-field + Plugin.Spec.add = function(self, plugin, ...) + if type(plugin) == "table" then + if M.renames[plugin[1]] then + Util.warn( + ("Plugin `%s` was renamed to `%s`.\nPlease update your config for `%s`"):format( + plugin[1], + M.renames[plugin[1]], + self.importing or "LazyVim" + ), + { title = "LazyVim" } + ) + plugin[1] = M.renames[plugin[1]] + end + end + return add(self, plugin, ...) + end +end + +function M.fix_lazy_file() + local Config = require("lazyvim.config") + -- Add support for the LazyFile event + local Handler = require("lazy.core.handler") + local Event = require("lazy.core.handler.event") + if M.use_lazy_file then + local _event = Event._event + ---@diagnostic disable-next-line: duplicate-set-field + Event._event = function(self, value) + return value == "LazyFile" and "User LazyFile" or _event(self, value) + end + else + ---@param plugin LazyPlugin + function Event:values(plugin) + local ret = Handler.values(self, plugin) + if ret["LazyFile"] or ret["User LazyFile"] then + for _, event in ipairs(M.lazy_file_events) do + ret[event] = event + end + ret["LazyFile"] = nil + ret["User LazyFile"] = nil + end + return ret + end + end +end + +return M