Configuration
LazyVim provides multiple layers of configuration. This page covers every config file and how to customize them.
Options (lua/config/options.lua)
This file sets vim.opt.* values. LazyVim loads default options first, then yours are merged on top.
-- These are loaded BEFORE plugins, but AFTER LazyVim defaults
-- You only need to specify what you want to change
vim.g.mapleader = " " -- Leader key (required before lazy.nvim)
vim.g.maplocalleader = "\\"
vim.opt.tabstop = 4 -- Your custom tab width
vim.opt.shiftwidth = 4 -- Override LazyVim default of 2
vim.opt.relativenumber = true
vim.opt.cursorline = true
Key Global Variables
| Variable | Default | Purpose |
|---|---|---|
vim.g.mapleader | " " | Leader key for which-key |
vim.g.maplocalleader | "\\" | Local leader |
vim.g.autoformat | true | Enable auto-format on save |
vim.g.snacks_animate | true | Enable snacks animations |
vim.g.lazyvim_picker | "auto" | Picker: telescope, fzf, auto |
vim.g.lazyvim_cmp | "auto" | Completion engine: nvim-cmp, blink.cmp, auto |
vim.g.root_spec | { "lsp", { ".git", "lua" }, "cwd" } | Root directory detection |
vim.g.ai_cmp | true | Use AI completion source |
vim.g.trouble_lualine | true | Show Trouble symbols in statusline |
LazyVim Default Options (Reference)
These are set automatically. You can override any in your options.lua:
-- Key LazyVim options (partial list)
opt.autowrite = true -- Auto-save
opt.clipboard = "unnamedplus" -- System clipboard
opt.completeopt = "menu,menuone,noselect"
opt.conceallevel = 2
opt.cursorline = true
opt.expandtab = true -- Spaces not tabs
opt.ignorecase = true
opt.mouse = "a" -- Mouse support
opt.number = true -- Line numbers
opt.relativenumber = true -- Relative line numbers
opt.scrolloff = 4 -- Context lines
opt.shiftwidth = 2
opt.smartcase = true -- Case-sensitive if capital
opt.smartindent = true
opt.splitbelow = true
opt.splitright = true
opt.tabstop = 2
opt.termguicolors = true -- True color
opt.timeoutlen = 300 -- which-key trigger time
opt.undofile = true -- Persistent undo
opt.updatetime = 200
opt.wrap = false
Keymaps (lua/config/keymaps.lua)
Your custom keymaps go here. They are loaded after LazyVim's defaults on the VeryLazy event.
-- Add your own keymaps here
vim.keymap.set("n", "<leader>wq", "<cmd>wq<cr>", { desc = "Save and Quit" })
-- Remove a LazyVim default
vim.keymap.del("n", "<leader>bd")
Use vim.keymap.del to remove LazyVim defaults, not an empty mapping.
Auto Commands (lua/config/autocmds.lua)
Custom autocmds go here:
-- Disable autoformat for Lua files
vim.api.nvim_create_autocmd("FileType", {
pattern = "lua",
callback = function()
vim.b.autoformat = false
end,
})
LazyVim's built-in autocmds include:
- checktime on focus gained (reload changed files)
- highlight on yank (brief flash)
- resize splits on VimResized
- last cursor position on BufReadPost
- close with
qfor help, qf, trouble, etc. - wrap + spell for markdown/text
- auto create dir on save
Plugins (lua/plugins/*.lua)
Each file under lua/plugins/ is a plugin spec (or list of specs). LazyVim auto-loads all of them.
Adding a Plugin
return {
"author/plugin-name",
event = "VeryLazy", -- When to load
opts = { ... }, -- Options passed to setup()
keys = { ... }, -- Keymaps
cmd = { ... }, -- Commands that trigger load
dependencies = { ... }, -- Other plugins needed
}
Disabling a Plugin
return {
{ "folke/trouble.nvim", enabled = false },
{ "akinsho/bufferline.nvim", enabled = false },
}
Customizing an Existing Plugin
Because of LazyVim's merge rules, you just specify what changed:
return {
"nvim-telescope/telescope.nvim",
opts = {
defaults = {
layout_strategy = "horizontal",
},
},
}
Adding a Dependency
return {
"hrsh7th/nvim-cmp",
dependencies = { "hrsh7th/cmp-emoji" },
---@param opts cmp.ConfigSchema
opts = function(_, opts)
table.insert(opts.sources, { name = "emoji" })
end,
}
Disabling Individual Keymaps
return {
"nvim-telescope/telescope.nvim",
keys = {
-- Disable a default keymap
{ "<leader>/", false },
-- Override with a new one
{ "<leader>ff", "<cmd>Telescope find_files<cr>", desc = "Find Files" },
},
}
Icons & Colorscheme
Configure the LazyVim plugin itself for colorscheme and icons:
return {
{
"LazyVim/LazyVim",
opts = {
colorscheme = "catppuccin", -- or "tokyonight" (default)
icons = {
diagnostics = {
Error = "✗ ",
Warn = "⚠ ",
},
},
},
},
}
LSP Configuration
LSP is configured through nvim-lspconfig options:
return {
"neovim/nvim-lspconfig",
opts = {
servers = {
-- Global LSP keymaps (applies to all servers)
["*"] = {
keys = {
{ "gd", false }, -- Disable go-to-definition
{ "K", "<cmd>echo 'custom hover'<cr>", desc = "Custom Hover" },
},
},
-- Server-specific config
pyright = {},
rust_analyzer = {},
lua_ls = {
settings = {
Lua = {
workspace = { checkThirdParty = false },
},
},
},
-- Disable a server
stylua = { enabled = false },
},
-- Global diagnostic config
diagnostics = {
underline = true,
virtual_text = { spacing = 4, prefix = "●" },
},
inlay_hints = { enabled = true },
},
}
Capability-Based Keymaps
Keymaps that only apply when the LSP server supports that capability:
keys = {
{ "<leader>ca", vim.lsp.buf.code_action, desc = "Code Action", has = "codeAction" },
{ "<leader>cr", vim.lsp.buf.rename, desc = "Rename", has = "rename" },
}
Formatting
LazyVim uses conform.nvim for formatting:
return {
"stevearc/conform.nvim",
opts = {
formatters_by_ft = {
lua = { "stylua" },
python = { "black" },
javascript = { "prettier" },
go = { "gofumpt", "goimports" },
rust = { "rustfmt" },
sh = { "shfmt" },
},
formatters = {
shfmt = { prepend_args = { "-i", "2", "-ci" } },
},
},
}
Toggle auto-format: <leader>uf (global), <leader>uF (buffer).
Mason (LSP/Linter/Formatter Installer)
Mason auto-installs tools. You can ensure specific ones:
return {
"williamboman/mason.nvim",
opts = {
ensure_installed = {
"stylua", -- Lua formatter
"shfmt", -- Shell formatter
"shellcheck", -- Shell linter
"flake8", -- Python linter
"prettier", -- Universal formatter
},
},
}
Related
- Plugins Overview — all pre-configured plugins
- Extras — enable language/editor extras
- Recipes — common customization patterns
- LazyVim Cheatsheet