LazyVim Configuration
LazyVim is a great Neovim setup that is pre-configured with reasonable features. It's better than starting from scratch. Here are my configuration settings that focus on Python, HTML, CSS, and JavaScript. Configuration files for LazyVim must be located in the ~/.config/nvim directory. More info about LazyVim is available at https://www.lazyvim.org.
Config
Files located in the ~/.config/nvim/lua/config directory.
-- config/autocmds.lua
-- Trim trailing white space when a file is saved
vim.api.nvim_create_autocmd("BufWritePre", {
pattern = "*",
command = [[%s/\s\+$//e]],
})
-- Detect Jinja filetypes, use .html and html so HTML LSP and Jinja LSP can coexist
vim.filetype.add({
extension = {
jinja = "jinja",
jinja2 = "jinja",
j2 = "jinja",
},
pattern = {
[".*%.html"] = "html",
},
})
-- config/keymaps.lua
vim.keymap.set("i", "jj", "<Esc>", { silent = true, desc = "Escape insert mode with jj" })
vim.keymap.set({ "n", "i" }, "<C-a>", "<Esc>ggVG", { desc = "Select all text with Ctrl-a" })
vim.keymap.set("x", "p", [["_dP]], { desc = "Paste without overwriting clipboard" })
-- config/options.lua
-- Turn off relative line numbers in the editor
vim.opt.relativenumber = false
-- Turn off concealing code block and other syntax in Markdown files
vim.opt.conceallevel = 0
-- Automatically format the file when it is saved
vim.g.autoformat = true
-- Use ty and ruff for Python programming
vim.g.lazyvim_python_lsp = "ty"
vim.g.lazyvim_python_ruff = "ruff"
-- Use prettier formatter without config file
vim.g.lazyvim_prettier_needs_config = false
Plugins
Files located in the ~/.config/nvim/lua/plugins directory.
-- plugins/colorscheme.lua
return {
"LazyVim/LazyVim",
opts = {
colorscheme = "catppuccin-nvim",
},
}
-- plugins/formatting.lua
return {
{
"stevearc/conform.nvim",
opts = function(_, opts)
opts.formatters_by_ft.jinja = { "djlint" }
opts.formatters_by_ft.html = function(bufnr)
local filename = vim.api.nvim_buf_get_name(bufnr)
if filename:match("/templates/.*%.html$") then
return { "djlint" }
end
return { "prettier" }
end
opts.formatters.djlint = {
prepend_args = { "--profile", "jinja" },
cwd = require("conform.util").root_file({
"pyproject.toml",
"djlint.toml",
".djlint.toml",
".djlintrc",
}),
}
end,
},
}
-- plugins/linting.lua
return {
{
"mfussenegger/nvim-lint",
opts = function(_, opts)
vim.list_extend(opts.events, { "TextChanged", "TextChangedI" })
opts.linters_by_ft.jinja = { "djlint" }
opts.linters_by_ft.html = { "djlint" }
opts.linters.djlint = {
prepend_args = { "--profile", "jinja" },
condition = function(ctx)
return ctx.filename:match("/templates/.*%.html$") ~= nil
or ctx.filename:match("%.jinja$") ~= nil
or ctx.filename:match("%.jinja2$") ~= nil
or ctx.filename:match("%.j2$") ~= nil
end,
}
end,
},
}
-- plugins/lspconfig.lua
-- In ruff, F821 overlaps ty unresolved-reference
return {
"neovim/nvim-lspconfig",
opts = {
inlay_hints = { enabled = false },
servers = {
ruff = {
init_options = {
settings = {
lint = {
ignore = { "F821" },
},
},
},
},
},
},
}
-- plugins/noice.lua
return {
"folke/noice.nvim",
opts = {
presets = {
lsp_doc_border = true, -- Add a border to LSP hover and docs
},
},
}
-- plugins/snacks.lua
return {
"snacks.nvim",
opts = {
indent = {
scope = {
enabled = false,
},
},
picker = {
sources = {
explorer = {
hidden = true,
},
grep = {
exclude = { "uv.lock" },
},
},
},
},
}
-- plugins/treesitter.lua
return {
"nvim-treesitter/nvim-treesitter",
opts = function(_, opts)
vim.list_extend(opts.ensure_installed, {
"css",
"jinja",
"swift",
})
end,
}