Skip to content

lazy‐loading nvim‐cmp and its extensions

Marc Jakobi edited this page Dec 2, 2024 · 6 revisions

Unfortunately, nvim-cmp relies on :h after-directory to register additional sources. This is not supported by Neovim's packadd, and thus does not work with native lazy-loading. We are hoping to fix this issue upstream.

Normally, if you want to lazy-load other plugins before a given plugin with lz.n (something we don't recommend), you can set lazy = true and use trigger_load in the before or after hook. If you want to lazy-load nvim-cmp sources, however, you additionally need to source the after-directory scripts. Or, alternately, you can register the sources manually by copy/pasting the code in the scripts to your plugin hooks.

Because lz.n follows the UNIX philosophy (do one thing well), and because it makes no assumptions about how or where a plugin is installed, it does not provide a function for sourcing after directories.

If you are using packadd to load your plugins, you can use rtp.nvim to source the after scripts in nvim-cmp's before hook.

Here's an example spec:

-- May need to be adjusted.
-- For example, replace <my-pack-dir> with where the plugins are installed.
local opt_dir = vim.fs.joinpath(vim.fn.stdpath("data"), "site", "pack", "<my-pack-dir>", "opt")

local lz = require("lz.n")

local function trigger_load_with_after(plugin_name)
  lz.trigger_load(plugin_name)
  local plugin_dir = vim.fs.joinpath(opt_dir, plugin_name)
  require("rtp_nvim").source_after_plugin_dir(plugin_dir)
end

lz.load({
  "nvim-cmp",
  event = "InsertEnter",
  after = function()
    local rtp = require("rtp_nvim")
    -- Add the nvim-cmp sources here
    local cmp_source_list = { "<list-of-cmp-sources-names>" }
    vim.iter(cmp_source_list):each(trigger_load_with_after)
  end
})

This may be more involved if using Nix, as the packpath is different for each plugin. You could use a function like the following to find a plugin's install directory:

local function trigger_load_with_after(plugin_name)
  for _, dir in ipairs(vim.opt.packpath:get()) do
    local glob = vim.fs.joinpath("pack", "*", "opt", plugin_name)
    local plugin_dirs = vim.fn.globpath(dir, glob, nil, true, true)
    if not vim.tbl_isempty(plugin_dirs) then
      lz.trigger_load(plugin_name)
      require("rtp_nvim").source_after_plugin_dir(plugin_dirs[1])
      return
    end
  end
end
Clone this wiki locally