Skip to main content

Neovim Configuration

This Neovim configuration is built on top of LazyVim, a modern Neovim configuration framework that provides a complete IDE experience out of the box.

LazyVim Setup

LazyVim provides a structured approach to Neovim configuration with:
  • Pre-configured LSP, formatting, and linting
  • Smart plugin management with lazy loading
  • Beautiful UI with statusline and bufferline
  • Extensive keybindings and which-key integration
  • Git integration with gitsigns and diffview

Plugin Structure

Plugins are organized in ~/.config/nvim/lua/plugins/:
nvim/lua/plugins/
├── coding.lua         # Completion, snippets, pairs
├── colorschemes.lua   # Color schemes
├── editor.lua         # Editor enhancements
├── formatting.lua     # Code formatting
├── linting.lua        # Code linting
├── lsp.lua           # LSP configuration
├── treesitter.lua    # Syntax highlighting
├── ui.lua            # UI components
└── util.lua          # Utilities

Key Features

LSP Support

Full Language Server Protocol integration with Mason for easy installation

Auto-completion

Intelligent code completion with nvim-cmp and snippet support

Formatting

Automatic code formatting with conform.nvim

Linting

Real-time code linting and diagnostics

Git Integration

Gitsigns for inline git blame, hunks, and diff viewing

Fuzzy Finding

Telescope for files, grep, and symbol search

Session Management

Automatic session persistence and restoration

Treesitter

Advanced syntax highlighting and code understanding

LSP Configuration

Language servers are managed with Mason and configured for optimal development:
return {
  {
    "williamboman/mason.nvim",
    config = function()
      require("mason").setup()
    end,
  },
  {
    "williamboman/mason-lspconfig.nvim",
    config = function()
      require("mason-lspconfig").setup({
        ensure_installed = { "lua_ls" },
      })
    end,
  },
  {
    "neovim/nvim-lspconfig",
    config = function()
      vim.diagnostic.config({
        underline = true,
        update_in_insert = false,
        virtual_text = { spacing = 4, prefix = "●" },
        severity_sort = true,
      })
      
      vim.lsp.enable("lua_ls")
    end,
  },
}

Diagnostic Configuration

  • Underline: Enabled for all diagnostics
  • Virtual Text: Shows with bullet prefix and 4px spacing
  • Severity Sort: Sorts diagnostics by severity
  • Update in Insert: Disabled for less distraction

Coding Features

Auto-completion

Powered by nvim-cmp with multiple sources:
sources = cmp.config.sources({
  { name = "nvim_lsp" },   -- LSP completions
  { name = "luasnip" },    -- Snippet completions
  { name = "buffer" },     -- Buffer text
  { name = "path" },       -- File paths
})
KeyAction
Ctrl + SpaceTrigger completion
Ctrl + BScroll docs up
Ctrl + FScroll docs down
Ctrl + EAbort completion
EnterConfirm selection
TabNext item / expand snippet
Shift + TabPrevious item

Auto Pairs

Automatic bracket, quote, and tag pairing:
{
  "nvim-mini/mini.pairs",
  opts = {
    modes = { insert = true, command = true, terminal = false },
    skip_next = [=[[%w%%%'%[%"%.%`%$]]=],
    skip_ts = { "string" },
    skip_unbalanced = true,
    markdown = true,
  },
}

Text Objects

mini.ai extends Neovim’s text objects:
  • af/if - Function outer/inner
  • ac/ic - Class outer/inner
  • ao/io - Block, conditional, loop
  • au/iu - Function call

Editor Options

Core editor settings in lua/config/options.lua:
opt.expandtab = true
opt.shiftwidth = 2
opt.tabstop = 2
opt.softtabstop = 2
opt.smartindent = true

Auto-save on Insert Leave

vim.api.nvim_create_autocmd("InsertLeave", {
  group = autosave_group,
  callback = function()
    if vim.bo.modifiable and vim.bo.buftype == "" then
      vim.cmd("silent! w")
    end
  end,
})
Files are automatically saved when leaving insert mode, reducing the need for manual saves.

Keymaps

Extensive keybindings organized by functionality in lua/config/keymaps.lua:

Telescope (Fuzzy Finder)

KeyAction
<leader>ffFind files
<leader>fgLive grep
<leader>fbBuffers
<leader>frRecent files
<leader>fsSearch in buffer
<leader>fwSearch word under cursor
KeyAction
gdGo to definition
grGo to references
giGo to implementation
gtGo to type definition

LSP Actions

map("n", "K", vim.lsp.buf.hover, { desc = "Hover" })
map("n", "<leader>ca", vim.lsp.buf.code_action, { desc = "Code Action" })
map("n", "<leader>cr", vim.lsp.buf.rename, { desc = "Rename" })
map("n", "<leader>e", vim.diagnostic.open_float, { desc = "Show Diagnostics" })
KeyAction
KShow hover documentation
<leader>caCode actions
<leader>crRename symbol
<leader>eShow diagnostics
[dPrevious diagnostic
]dNext diagnostic

Git Operations

KeyAction
]hNext hunk
[hPrevious hunk
]HLast hunk
[HFirst hunk
KeyAction
<leader>ghsStage hunk
<leader>ghrReset hunk
<leader>ghSStage buffer
<leader>ghRReset buffer
<leader>ghuUndo stage hunk
<leader>ghpPreview hunk inline
<leader>ghbBlame line
<leader>ghdDiff this

Formatting

map("n", "<leader>cf", function()
  require("conform").format({ bufnr = vim.api.nvim_get_current_buf() })
end, { desc = "Format Buffer" })
KeyAction
<leader>cfFormat buffer
<leader>cFFormat injected languages

Trouble (Diagnostics)

KeyAction
<leader>xxToggle diagnostics
<leader>xXBuffer diagnostics
<leader>csSymbols
<leader>cSLSP references
[qPrevious item
]qNext item

Flash (Quick Navigation)

map("n", "s", require("flash").jump, { desc = "Flash" })
map("n", "S", require("flash").treesitter, { desc = "Flash Treesitter" })
KeyAction
sFlash jump
SFlash treesitter
Ctrl + SpaceTreesitter selection

Session Management

KeyAction
<leader>qsRestore session
<leader>qSSelect session
<leader>qlRestore last session
<leader>qdDon’t save session

Todo Comments

KeyAction
]tNext todo comment
[tPrevious todo comment
<leader>xtTodo list (Trouble)
<leader>stSearch todos (Telescope)

Auto Commands

Several auto commands enhance the editing experience:

Highlight on Yank

vim.api.nvim_create_autocmd("TextYankPost", {
  callback = function()
    vim.highlight.on_yank({ higroup = "Visual", timeout = 200 })
  end,
})

Remove Trailing Whitespace

vim.api.nvim_create_autocmd("BufWritePre", {
  callback = function()
    vim.cmd([[%s/\s\+$//e]])
  end,
})

Restore Cursor Position

vim.api.nvim_create_autocmd("BufReadPost", {
  callback = function()
    local line = vim.fn.line("'\"")
    if line > 1 and line <= vim.fn.line("$") then
      vim.cmd('exe "normal! g\'\\""')
    end
  end,
})

Snippets

LuaSnip provides snippet expansion with friendly-snippets:
{
  "L3MON4D3/LuaSnip",
  version = "v2.*",
  build = "make install_jsregexp",
  opts = {
    history = true,
    delete_check_events = "TextChanged",
  },
}
KeyAction
Ctrl + KExpand/jump forward
Ctrl + JJump backward
Use <leader>ll to open Lazy plugin manager and <leader>lm to open Mason for LSP/tool installation.

Plugin Manager

Lazy.nvim handles all plugin management with lazy loading for fast startup times. Plugins are automatically installed on first launch.
Make sure to run :checkhealth after installation to verify all dependencies are correctly installed.

Build docs developers (and LLMs) love