I can do :source $MYVIMRC
to successfully reload my init.lua
from in a running nvim instance, however, any files that are included with require
or pcall(require, fname)
do not seem to want to reload. Is there a way of doing this?
See Programming in Lua : 8.1, especially the part about _LOADED
.
That sounds like the solution, but when I look at _LOADED
the table itself seems to be null, even after my entire init.lua
has run… is there some other trick I am missing to access it?
Googling around makes me think it’s package.loaded
.
“This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.”
Ah yeah, that’s always a footgun, although I really like that book I found it a reference to package.loaded
in the neovim docs, though: Nvim documentation: lua, first code sample.
Where do you see that? I get zero hits for _LOADED
under that link.
I found the need/possibility to use package.loaded
under that link. First code sample:
:lua print(vim.inspect(package.loaded))
Granted, the link went to the wrong tag, I’ve fixed it now
Oh, right, then I misunderstood – I thought “it” in your third comment referred to what you suggested in your first comment
Rereading my post, I definitely see why you would think that Oh well…
That is because in lua once a module is required it is then cached for the entirety of the runtime, so sourcing just $MYVIMRC
isn’t enough to reload all the modules that are required inside your init.lua
.
What you need to do is set those loaded modules to nil
and then finally source your init.lua
, and on the next re-source it will re-require the file instead of the cached one.
I stole this code from plenary and simplified it for my use case but the concept is the same. You want to make sure all your lua files are scoped within a namespace, what this means is to have all your lua files inside lua/<namespace>
where (in my case I use my username: cnull) is the name of the directory, and then match all the modules that start with the namespace and set them to nil
. Below is the code along with a keymap and command you can set. Just replace the pattern in name:match()
from cnull
to your namespace.
function _G.ReloadConfig()
for name,_ in pairs(package.loaded) do
if name:match('^cnull') then
package.loaded[name] = nil
end
end
dofile(vim.env.MYVIMRC)
end
vim.api.nvim_set_keymap('n', '<Leader>vs', '<Cmd>lua ReloadConfig()<CR>', { silent = true, noremap = true })
vim.cmd('command! ReloadConfig lua ReloadConfig()')
If you want to use plenary to reload instead, then you just need to require it and give it the modulename aka your namespace/directory name.
require("plenary.reload").reload_module("cnull") -- replace with your own namespace
Rather amazingly, I still can’t seem to find a fully satisfactory solution to this problem. package.loaded
returns a seemingly arbitrary subset of the loaded files. I have yet to find a list anywhere that contains the explicit or implicit names of files loaded within my init.lua
. Rather frustrating as you’d think this would be among the first things they’d have tried when developing the init.lua
functionality.
Maybe you could post a minimal example for what you tried and what didn’t work? If you’re sure it doesn’t work the expected way you could open an issue, it might at least be a documentation problem.
Not sure why you would want to check for all the loaded files, since the only files that needed to be reloaded would be your own config. At this point unfortunately, you will have to re-source the way I mentioned or via plenary of you have files inside lua/
directory in your user config.
But if you insist, then you can always debug with the print command and vim.inspect
and see the output is. In this case, running in nvim:
:lua print(vim.inspect(package.loaded, { depth = 1 }))
Will print out all the packages/modules loaded from nvim and your init.lua
.
Now to know EXACTLY which packages were loaded from your init.lua
? Well… you can always look into your init.lua
file and grep for all the require
code that’s in there.
I have improved the reload function by saving the hlsearch status and restoring after reloading:
function _G.ReloadConfig()
local hls_status = vim.v.hlsearch
for name,_ in pairs(package.loaded) do
if name:match('^cnull') then
package.loaded[name] = nil
end
end
dofile(vim.env.MYVIMRC)
if hls_status == 0 then
vim.opt.hlsearch = false
end
end
Now my improvement works, which means if your hlsearch is enabled it will be enabled on ReloadConfig() otherwise it will not. The secret is getting the value of vim.v.hlsearch
.
There were a typo, sorry guys!
I am a new neovim user, so i guess my solution may not work for some edge cases.
This function flushes the module of current buffer.
Flush = function()
local s = vim.api.nvim_buf_get_name(0)
if string.match(s, '^' .. cfg .. '*') == nil then
print('fuck')
return
end
s = string.sub(s, 6 + string.len(cfg), -5)
local val = string.gsub(s, '%/', '.')
package.loaded[val] = nil
end
You can call it whenever you write to a buffer.
autocmd BufWrite *.lua,*vim call v:lua.Flush()
This way, after you execute :source $MYVIMRC
it will also reload changed lua module
Maybe you can write a wrapper around require
that first checks for and removes the file from package.loaded
if it appears there. I could use something like that myself.
How can I change this function to put it inside my ~/.config/nvim/lua/utils.lua ?
I wan to call it like this:
vim.cmd('command! ReloadConfig lua require('utils').reloadconfig()')
You want to make it lua module, so instead of _G
you do M
and return that variable M
:
-- utils.lua
local M = {}
function M.reloadconfig()
-- ...
end
return M
And the command should work.