Skip to content

Latest commit

 

History

History
292 lines (220 loc) · 6.2 KB

File metadata and controls

292 lines (220 loc) · 6.2 KB

Lazy Loading

leanpack.nvim provides multiple lazy loading mechanisms to optimize Neovim startup time.

Overview

Lazy loading defers plugin activation until needed. This reduces startup time by only loading plugins when you use their features.

leanpack.nvim implements four lazy loading trigger types:

  1. Event - Load when a Neovim event fires
  2. Command - Load when a user command is called
  3. Keymap - Load when a key is pressed
  4. Filetype - Load when a file type is detected

Event Trigger

Load a plugin when a Neovim event occurs.

Syntax

return {
  'plugin/name',
  event = 'EventName',
}

Common Events

Event Description
VeryLazy After UIEnter (default for lazy plugins)
BufReadPre Before reading a buffer
BufReadPost After reading a buffer
BufNew For new buffers
TabEnter When switching tabs
InsertEnter When entering insert mode
CmdlineEnter When entering command line

Examples

-- Load on InsertEnter event
return {
  'windwp/nvim-autopairs',
  event = 'InsertEnter',
  opts = {},
}

-- Load on multiple events
return {
  'user/plugin',
  event = { 'InsertEnter', 'CmdlineEnter' },
}

-- Load with file pattern
return {
  'user/lua-syntax',
  event = 'BufReadPre *.lua',
}

-- Load very lazily (after startup)
return {
  'user/plugin',
  event = 'VeryLazy',
}

Command Trigger

Load a plugin when a user command is invoked.

Syntax

return {
  'plugin/name',
  cmd = 'CommandName',
}

Examples

-- Single command
return {
  'nvim-tree/nvim-tree.lua',
  cmd = { 'NvimTreeToggle', 'NvimTreeFocus' },
  opts = {},
}

-- Multiple commands
return {
  'user/plugin',
  cmd = { 'Cmd1', 'Cmd2', 'Cmd3' },
}

How It Works

  1. leanpack.nvim creates a temporary stub command
  2. When the user runs the command, the stub loads the plugin
  3. The stub deletes itself and runs the actual command

Keymap Trigger

Load a plugin when a key is pressed.

Syntax

return {
  'plugin/name',
  keys = 'keyseq',
}

Or with options:

return {
  'plugin/name',
  keys = {
    { 'keyseq', function() ... end, mode = 'n', desc = 'Description' },
  },
}

Examples

-- Simple key sequence
return {
  'folke/flash.nvim',
  keys = 's',
}

-- With function
return {
  'folke/flash.nvim',
  keys = {
    { 's', function() require('flash').jump() end, mode = { 'n', 'x', 'o' }, desc = 'Flash' },
    { 'S', function() require('flash').treesitter() end, mode = { 'n', 'x', 'o' }, desc = 'Flash Treesitter' },
  },
}

-- With command
return {
  'user/plugin',
  keys = { '<leader>p', '<cmd>PluginCmd<cr>', mode = 'n', desc = 'Run Plugin' },
}

How It Works

  1. leanpack.nvim creates a temporary keymap
  2. When the key is pressed, the plugin loads
  3. The keymap deletes itself and re-feeds the keystrokes

Filetype Trigger

Load a plugin when a file type is detected.

Syntax

return {
  'plugin/name',
  ft = 'filetype',
}

Examples

-- Single filetype
return {
  'rust-lang/rust.vim',
  ft = 'rust',
}

-- Multiple filetypes
return {
  'user/plugin',
  ft = { 'lua', 'vim', 'python' },
}

Critical: Event Re-triggering

When using filetype triggers, leanpack.nvim automatically re-triggers buffer events to ensure LSP/Treesitter attaches:

-- After loading, leanpack.nvim does:
vim.api.nvim_exec_autocmds("BufReadPre", { buffer = bufnr })
vim.api.nvim_exec_autocmds("BufReadPost", { buffer = bufnr })
vim.api.nvim_exec_autocmds("FileType", { buffer = bufnr })

This ensures that newly loaded plugins analyze the current buffer.

Require/Module Trigger

Load a plugin automatically when its main Lua module is required.

Syntax

Leanpack natively intercepts require calls matching either:

  1. The explicit main field defined in the spec.
  2. The implicitly auto-detected main module name.
return {
  'nvimtools/none-ls.nvim',
  -- Because `opts` is here, if no `main` is present leanpack deduces it as `null-ls`.
  -- Thus, `require('null-ls')` automatically triggers loading.
  opts = {},
}

-- Or with explicit main
return {
  'user/repo',
  main = 'custom_module', -- require('custom_module') will load this!
}

How It Works

  1. leanpack.nvim installs a non-intrusive lookup loader in package.loaders at startup.
  2. When code calls require('module_name'), it resolves against the plugin's main reference.
  3. If it matches an unloaded plugin, it loads it immediately and caches the module.

Comparison

Trigger Best For Overhead
Event General features Very low
Command CLI tools Very low
Keymap User-facing features Low
Filetype Language tools Low
Module Autoload via require Very low

Best Practices

1. Choose the Right Trigger

  • UI plugins → Command or keymap trigger
  • Language servers → Filetype trigger
  • General plugins → Event trigger
  • Colorscheme → No trigger (load eagerly)

2. Use Priority for Ordering

-- Load colorschemes early
return {
  'folke/tokyonight.nvim',
  priority = 1000,
  config = function()
    vim.cmd('colorscheme tokyonight')
  end,
}

3. Group Dependencies

Make sure dependencies are loaded before their parent:

return {
  'nvim-telescope/telescope.nvim',
  cmd = 'Telescope',
  dependencies = {
    'nvim-lua/plenary.nvim',
  },
}

Performance

leanpack.nvim's lazy loading is optimized:

  • Self-cleaning package.loaders - Installs a lightweight loader at position 2 for module-based lazy loading, then auto-removes it once all module-triggered plugins are loaded (unlike lazy.nvim's permanent interception)
  • Self-destructing triggers - Autocmds, commands, and keymaps delete themselves after first trigger
  • O(V + E) dependency resolution - Efficient topological sorting

Next Steps