Building a Modern Neovim Config with Lua and Lazy.nvim
Building a Modern Neovim Config
Neovim has become my editor of choice due to its blazing speed and infinite extensibility. In this post, I'll dissect my configuration, which focuses on a clean UI, robust LSP support, and seamless navigation.
The Architecture: Lazy.nvim
I use lazy.nvim as my plugin manager. It allows for a highly modular structure where every plugin category gets its own file.
My init.lua is surprisingly simple. It bootstraps lazy and imports the plugin specifications:
-- init.lua
require("lazy").setup({
{ import = "plugins.core" }, -- Themes, Dashboard
{ import = "plugins.ui" }, -- Neo-tree, Noice
{ import = "plugins.editing" }, -- Treesitter, Comments
{ import = "plugins.completion" }, -- Cmp, Snippets
{ import = "plugins.lsp" }, -- LSP Config
{ import = "plugins.formatting" }, -- Conform, None-ls
{ import = "plugins.utilities" }, -- Copilot, Which-key
}, {
defaults = { lazy = true },
checker = { enabled = false },
})
Core Settings
Before loading plugins, I set reasonable defaults in lua/core/options.lua. A few highlights include:
relativenumber = true: Essential for relative jumps.clipboard = 'unnamedplus': Syncs the system clipboard with Neovim.scrolloff = 4: Keeps context visible above and below the cursor.undofile = true: Persists undo history even after closing the file.
Keymaps & Workflow
I've mapped my Leader key to <Space>, which is ergonomic and standard for modern setups. You can find my full list in lua/core/keymaps.lua.
Window Management
I avoid using the mouse for window resizing or navigation:
-- Resize with arrows
vim.keymap.set("n", "<Up>", ":resize -2<CR>", opts)
vim.keymap.set("n", "<Down>", ":resize +2<CR>", opts)
-- Navigate splits using Leader + hjkl
vim.keymap.set("n", "<leader>h", ":wincmd h<CR>", opts)
vim.keymap.set("n", "<leader>l", ":wincmd l<CR>", opts)
File Operations
Quick saving and quitting are muscle memory:
vim.keymap.set("n", "<leader>s", "<cmd>w<CR>", { desc = "Save file" })
vim.keymap.set("n", "<leader>q", "<cmd>q<CR>", { desc = "Exit vim" })
The Visual Stack
Aesthetics play a huge role in productivity. I use the GitHub Dark Default theme via github-nvim-theme to match the rest of my developer environment.
For the interface, I use:
- Neo-tree: A file explorer that supports git status and icons.
- Lualine: A fast and configurable status line.
- Noice.nvim: Replaces the command line with nice popups and notifications.
Intelligence: LSP & Completion
My IDE-like features are powered by Native LSP and nvim-cmp.
I use mason.nvim to manage language servers like clangd (C++), pyright (Python), and ts_ls (TypeScript). Formatting is handled by conform.nvim, which ensures my code is always clean on save.
-- lua/plugins/formatting.lua
format_on_save = function(bufnr)
return { timeout_ms = 500, lsp_fallback = true }
end
I've also integrated GitHub Copilot for AI-powered suggestions, mapped to <Tab> for seamless acceptance.
Conclusion
This configuration strikes a balance between a minimal editor and a full-blown IDE. It starts fast, looks great, and provides all the tools I need for heavy coding sessions in C++, Lua, or Web Development.
Feel free to fork my setup from my GitHub repository!