← Back Home

Reloading Neovim Config With Telescope

  1. neovim
  2. lua
  3. telescope

Recently, I’ve decided to change my Neovim configuration to use Lua. If you want to do it too, this guide has much information about what you need to do.

In Lua, when you require a module, it is cached, so next time you require it, you are not getting the changes. The problem with this is that I usually have two open tabs with a few splits each when I’m working. After changing something in my config, I need to close Neovim to load everything again.

But, for my luck, a project named plenary.nvim exposes a function that can reload the Lua module. So I decided to create a Telescope picker to reload the module I changed.

After some research and copying a few snippets from TJ DeVries, I developed a solution that works pretty well.

The idea is to use Telescope to list my Lua modules, and when I click ctrl+e, it will call the Plenary function to reload the module. So this is how I did it.

telescope screenshot

I’ve namespaced my modules with ju, so my nvim folder looks like this:

├── init.lua
├── lua
│   └── ju
│       ├── colors.lua
│       ├── compe.lua
│       ├── elixir.lua
│       ├── general.lua
│       ├── git.lua
│       ├── go.lua
│       ├── keymappings.lua
│       ├── lsp
│       │   └── init.lua
│       ├── plugins.lua
│       ├── settings.lua
│       ├── telescope.lua
│       ├── treesitter
│       │   └── init.lua
│       └── utils
│           ├── init.lua
│           └── reload.lua

in lua/ju/utils/reload.lua, I have two global helper functions. The first one just prints using the Neovim API, the second uses Plenary to reload the module and require it again.

P = function(v)
  print(vim.inspect(v))
  return v
end

if pcall(require, "plenary") then
  RELOAD = require("plenary.reload").reload_module

  R = function(name)
    RELOAD(name)
    return require(name)
  end
end

In my Telescope config, I’ve created a new picker that will list just the files inside .config/nvim/lua, with a new keybinding to execute the above function.

I’ve added comments to the code, so it will be easier to follow.

local M = {}

function M.reload()
  -- Telescope will give us something like ju/colors.lua, 
  -- so this function convert the selected entry to 
  -- the module name: ju.colors
  local function get_module_name(s)
    local module_name;

    module_name = s:gsub("%.lua", "")
    module_name = module_name:gsub("%/", ".")
    module_name = module_name:gsub("%.init", "")

    return module_name
  end

  local prompt_title = "~ neovim modules ~"

  -- sets the path to the lua folder
  local path = "~/.config/nvim/lua"

  local opts = {
    prompt_title = prompt_title,
    cwd = path,

    attach_mappings = function(_, map)
     -- Adds a new map to ctrl+e.
      map("i", "<c-e>", function(_)
        -- these two a very self-explanatory
        local entry = require("telescope.actions.state").get_selected_entry()
        local name = get_module_name(entry.value)

        -- call the helper method to reload the module
        -- and give some feedback
        R(name)
        P(name .. " RELOADED!!!")
      end)

      return true
    end
  }

  -- call the builtin method to list files
  require('telescope.builtin').find_files(opts)
end

return M;

I have this map that calls the function.

vim.api.nvim_set_keymap('n', '<Leader>qr',  '<cmd>:lua require("ju.telescope").reload()<CR>', { noremap = true, silent = true })

Now, when you change your config, you can use Telescope to reload it.