Lua Session 04: Plugins
Plugin management. This session covers lazy.nvim plugin specs, module organization, and lazy loading patterns.
Pre-Session State
-
Know vim.opt, vim.keymap, vim.api
-
Understand autocommands
-
Can create user commands
Lesson 1: lazy.nvim Basics
Concept: lazy.nvim uses declarative plugin specs.
Exercise 1.1: Simple plugin spec
-- Minimal spec (just the repo)
return {
"nvim-lua/plenary.nvim"
}
Exercise 1.2: Plugin with options
return {
"folke/which-key.nvim",
event = "VeryLazy", -- Load lazily
opts = {
-- Options passed to setup()
plugins = {
spelling = { enabled = true }
}
}
}
Exercise 1.3: Plugin with config function
return {
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
config = function()
require("nvim-treesitter.configs").setup({
ensure_installed = { "lua", "python", "bash" },
highlight = { enable = true },
})
end
}
Lesson 2: Lazy Loading
Concept: Load plugins only when needed for faster startup.
Exercise 2.1: Load on event
return {
"numToStr/Comment.nvim",
event = { "BufReadPre", "BufNewFile" }, -- Load when opening file
opts = {}
}
Exercise 2.2: Load on filetype
return {
"mfussenegger/nvim-dap-python",
ft = "python", -- Load only for Python files
config = function()
require("dap-python").setup("python")
end
}
Exercise 2.3: Load on command
return {
"folke/trouble.nvim",
cmd = { "Trouble", "TroubleToggle" }, -- Load when command used
opts = {}
}
Exercise 2.4: Load on keymap
return {
"nvim-telescope/telescope.nvim",
keys = {
{ "<leader>ff", "<cmd>Telescope find_files<cr>", desc = "Find Files" },
{ "<leader>fg", "<cmd>Telescope live_grep<cr>", desc = "Live Grep" },
},
opts = {}
}
Lesson 3: Dependencies
Concept: Declare plugin dependencies for load ordering.
Exercise 3.1: Simple dependency
return {
"nvim-telescope/telescope.nvim",
dependencies = {
"nvim-lua/plenary.nvim" -- Required by telescope
},
opts = {}
}
Exercise 3.2: Multiple dependencies
return {
"nvim-telescope/telescope.nvim",
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-tree/nvim-web-devicons",
{
"nvim-telescope/telescope-fzf-native.nvim",
build = "make"
}
},
config = function()
require("telescope").setup({})
require("telescope").load_extension("fzf")
end
}
Lesson 4: Module Structure
Concept: Organize plugins in separate files.
Exercise 4.1: Directory structure
~/.config/nvim/
├── init.lua -- Bootstrap lazy.nvim
├── lua/
│ └── plugins/
│ ├── init.lua -- Empty or imports
│ ├── colorscheme.lua -- Theme plugins
│ ├── editor.lua -- Editor enhancements
│ ├── lsp.lua -- LSP configuration
│ └── telescope.lua -- Fuzzy finder
Exercise 4.2: Loading plugin directory
-- init.lua
require("lazy").setup({
spec = {
{ import = "plugins" } -- Load all from lua/plugins/
}
})
Exercise 4.3: Single plugin file
-- lua/plugins/telescope.lua
return {
"nvim-telescope/telescope.nvim",
dependencies = { "nvim-lua/plenary.nvim" },
keys = {
{ "<leader>ff", "<cmd>Telescope find_files<cr>", desc = "Find Files" },
},
opts = {
defaults = {
layout_strategy = "horizontal",
}
}
}
Exercise 4.4: Multiple plugins in one file
-- lua/plugins/editor.lua
return {
-- Comment.nvim
{
"numToStr/Comment.nvim",
event = { "BufReadPre", "BufNewFile" },
opts = {}
},
-- Autopairs
{
"windwp/nvim-autopairs",
event = "InsertEnter",
opts = {}
},
-- Surround
{
"kylechui/nvim-surround",
event = "VeryLazy",
opts = {}
}
}
Summary: What You Learned
| Concept | Syntax | Example |
|---|---|---|
Plugin spec |
|
|
opts |
|
Passed to setup() |
config |
|
Custom configuration |
event |
|
Load on event |
ft |
|
Load on filetype |
cmd |
|
Load on command |
keys |
|
Load on keymap |
dependencies |
|
Load order |
import |
|
Load plugin files |
Exercises to Complete
-
[ ] Create a plugin spec for Comment.nvim with lazy loading
-
[ ] Add telescope with keymaps and dependencies
-
[ ] Organize your plugins into separate files
-
[ ] Add a filetype-specific plugin (e.g., markdown preview)
Next Session
Session 05: LSP - lspconfig, mason, diagnostics.
Session Log
| Timestamp | Notes |
|---|---|
Start |
<Record when you started> |
End |
<Record when you finished> |