-
Notifications
You must be signed in to change notification settings - Fork 365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: reloading plugins #445
Comments
I also came up with an interesting alternative to using A proposal to plugin authors: After that, since -- in the plugin spec
config = true
-- lazy.nvim converts above to something like this
config = function(plugin, opts)
return require(plugin.name).setup(opts)
end Maybe this is a bit too much, but I just wanted to share my idea :) |
I'm actually working on something like this, but I'm still not sure I should add it. More details soon. But it involves a new property For noice for example: {
"folke/noice.nvim",
event = "VeryLazy",
unload = function()
require("noice").disable()
end,
} What the reloading currently does:
It all seems to work pretty good like this, especially with some custom |
That sounds great! If plugin authors start to provide |
reloadable
key to plugin spec
I changed the issue title to be more generic, so that people can discuss and collect ideas about said features. |
I needed something like this for the convenience of quickly testing plug-in changes during development, if someone needs an intermediate solution, the below serves me well and can be easily modified to any setup, it’s quite simple, unload specific lua patterns from
M.reload_config = function()
M.unload_modules({
{ "^options$", fn = function() require("options") end },
{ "^autocmd$", fn = function() require("autocmd") end },
{ "^keymaps$", fn = function() require("keymaps") end },
{ "^utils$" },
{ "^workdirs$" },
{ mod = "ts%-vimdoc" },
{ mod = "smartyank", fn = function() require("smartyank") end },
{ mod = "fzf%-lua", fn = function() require("plugins.fzf-lua.setup").setup() end },
})
-- re-source all language specific settings, scans all runtime files under
-- '/usr/share/nvim/runtime/(indent|syntax)' and 'after/ftplugin'
local ft = vim.bo.filetype
vim.tbl_filter(function(s)
for _, e in ipairs({ "vim", "lua" }) do
if ft and #ft > 0 and s:match(("/%s.%s"):format(ft, e)) then
local file = vim.fn.expand(s:match("[^: ]*$"))
vim.cmd("source " .. file)
M.warn("RESOURCED " .. vim.fn.fnamemodify(file, ":."))
return s
end
end
return nil
end, vim.fn.split(vim.fn.execute("scriptnames"), "\n"))
end and the reload function: M.unload_modules = function(patterns)
for _, p in ipairs(patterns) do
if not p.mod and type(p[1]) == "string" then
p = { mod = p[1], fn = p.fn }
end
local unloaded = false
for m, _ in pairs(package.loaded) do
if m:match(p.mod) then
unloaded = true
package.loaded[m] = nil
M.info(string.format("UNLOADED module '%s'", m))
end
end
if unloaded and p.fn then
p.fn()
M.warn(string.format("RELOADED module '%s'", p.mod))
end
end
end |
Just popping in here, I was going to ask if a PR would be welcome for setting up reloading plugins lol. Edit: Alternatively, feel free to yoink the reload code powering import, it will likely cover most of the bases you are looking for and (with a bit of coercion into your current codebase) :) |
It's not as simple as that, since you need to properly update the lazy loading handlers as well. Anyhow, the code to reload plugins is actually live already. It's just not used at this point lazy.nvim/lua/lazy/core/loader.lua Line 225 in e285559
Right now, you could use this like: local plugin = require("lazy.core.config").plugins["trouble.nvim"]
require("lazy.core.loader").reload(plugin) Still need to do more proper testing, documenting everything and optionally included automatic reloading on install/updates. |
@idr4n you should not use Other plugins typically have an autocmd that triggers on colorscheme changes. If not that should be fixed in those plugins. Also, for proper reloading, complex plugins would eventually have to implement a And why do you even reload tokyonight? Your code makes no sense at all. reload is NOT the way to go here |
@folke Sorry I just moved that to a discussion instead. Thanks for replying to this. I was reloading plugins as I have some highlight groups defined in the tokyonight config, that's why, same for gitsigns. But you are right, I was just trying things to see whether it works or not. Unfortunately plugins such as lualine don't have an autocmd that triggers changes on colorsheme or an option to change the theme without restarting Neovim. But thanks for letting me know that reload in not the way to go in this case. Appreciate it! |
@folke This is very interesting. I've implemented my own reloaders for my plugins, e.g. for VimTeX (which is mostly Vimscript). If lazy.nvim should ever have a "spec" for reloading, then I would be more than happy to update my plugins to enable some kind of seamless integration. |
@lervag the reloading is a two step process. First lazy completely deactivates a plugin by removing any lazy handlers, unloading its lua modules and clearing Once a plugin is deactivated, the plugin is loaded again as if during startup. If you want to provide reloading support for lazy, you would need to add a file local M = {}
function M.deactivate()
-- add any logic to deactivate here
end Alternatively, you can provide users with a code snippet they can use to add a Do know that this is all still very experimental :) You can find the actual code in lazy that does deactivation here: https://github.com/folke/lazy.nvim/blob/main/lua/lazy/core/loader.lua#L187 |
Thanks, @folke!
Does this include adjusting the
I assume that lazy's deactivation does not automatically remove all mappings and commands defined by a plugin? And that this is what the plugin's main lua module would have to implement? For VimTeX (and possibly other Vimscript based plugins), I believe we might want to use a reloader that uses another mechanism: i.e. to manually re-source all (previously sourced) vimscript files. I'm not sure you want to implement that, but it may be interesting to at least have some kind of hook that we could use.
I like experimental :) |
clearing keymaps and autocmds should be handled by the plugin indeed, but in most cases that's not needed for a reload. After deactivation, the plugin is loaded again, meaning for vimscript that their plugin ftplugin etc files are sourced again. I'll look into your idea to re-source, or unsource (if that's a thing, need to check) any other vimscript files part of the plugin's rtp. But again, probably not a good idea for you to make any changes to vimtex at this point. reloading/deactivating of plugins is currently not even exposed to lazy users :) |
One sub-feature which should be easy(er) to implement: hot-reloading the Edit: Not asking for removed keys to be unmapped (although that would be nice), but just updating new/modified keys should be fine. |
lazy keys are already handled by a reload, so those are fine |
No, I'm talking about actually setting the keymaps. So if I add the keys section here like this: {
"cshuaimin/ssr.nvim",
keys = {
{ "<leader>lR", '<cmd>lua require("ssr").open()<cr>', desc = "Structural Search & Replace" },
},
opts = {},
} The keys should automatically be usable from then on. Same if I change what happens when an existing key is pressed. I'm on the latest LazyVim btw. |
I'm talking about the same thing. Reload supports that. |
Cool, thanks! I'll just keep watching and will consider changes at a later stage, then :) |
I just added automatic re-sourcing of loaded vimscript for the plugin that you want to reload. Thank you for the idea @lervag! I also added Still all very experimental, so use with caution. Things will likely break |
Wow, thanks; that was fast! I was not aware of |
Be aware that reloading is still not automatic. |
I'm way out of my depth with this, but I've wondered about an alternative approach to reloading: restoring a "clean slate" state for the neovim version, and the reloading the config. This would include restoring global variables, mappings, highlights, autocommands, lua _G object and package.loaded members. Probably all LSP servers would need to be terminated and be restarted after reloading too. After reloading, all buffers have all ftplugin and FileType autocommands rerun. There are probably a whole lot of reasons this won't work. Some I can think of: what should happen to buffers from plugins like neotree, especially if they affect the current window layout; buffer variables a user might have set manually. |
@kamalmarhubi I think that level of reloading should be supported by Neovim itself. |
I dug into this a bit in my deprecated project I attempted to do a deep copy of the various vim states available but quite a few of the vim variables are faux lua tables, so you can't really copy them without knowing exactly what you are trying to copy. Which is tough when you are trying to copy "everything". That would have to be something that is done in vimscript I think, and I just didn't feel like trying to figure that out. Honestly, @WieeRd is right, state management should be left to neovim (and this is not something that neovim supports currently). |
Did you check the docs?
Is your feature request related to a problem? Please describe.
I wanted to have a convenient way to reload plugin configs without restarting Neovim.
Not reloading plugin specs, I mean running all the
config
functions again.The problem here is that some plugins are safe to reload, while some are not.
There is no guarantee running
.setup()
for the second time will break the plugin or not.Describe the solution you'd like
Add
reloadable
key withboolean?
type to plugin specs.It can be used to explicitly specify if the plugin is safe to reload or not.
Add command
:Lazy reload [plugins]
(and.reload()
API)It'll run the
config
function of the specified plugins.Without any arguments, all plugins with
reloadable = true
are used.Add shortcut
r
andR
inside:Lazy
window.r
reloads the plugin under the cursor, andR
is the same as:Lazy reload
.Add these options to
lazy.setup()
defaults.reloadable
- makes pluginsreloadable
by default.change_detection.reload
- auto reload plugins when config change is detected.The text was updated successfully, but these errors were encountered: