Neovim Configuration (LazyVim)

A LazyVim-based setup focused on Go and Zig development, with LSP, debugging, test running, task running, AI chat, database tooling, and a which-key cheat sheet. Everything is lazy-loaded so plugins only activate for the filetype or command that needs them.

Prerequisites

  • Neovim >= 0.11 (developed on 0.12.x; 0.11+ is required for the modern vim.lsp / root_markers API used by some servers)
  • Git
  • A Nerd Font (icons in the explorer, statusline, dadbod UI, etc.)
  • Node.js — TypeScript/JSON/YAML/web LSPs and prettier
  • Gogopls, delve, gofumpt, goimports
  • Zig — the zig toolchain on $PATH (for LSP, build/run, tests, debug)
  • Python (optional)pyright + ruff are configured if you use it

Most language servers, linters, formatters, and DAP adapters install automatically through Mason on first launch.

Installation

  1. Back up any existing config:

    mv ~/.config/nvim ~/.config/nvim.bak
    mv ~/.local/share/nvim ~/.local/share/nvim.bak
    mv ~/.local/state/nvim ~/.local/state/nvim.bak
    mv ~/.cache/nvim ~/.cache/nvim.bak
    
  2. Clone:

    git clone https://git.samoneal.io/sam_oneal/nvim-config.git ~/.config/nvim
    
  3. Launch Neovim. lazy.nvim bootstraps itself and installs all plugins.

  4. Install tooling with :Mason (or :MasonInstall <tool>). Check health with :checkhealth and LSP attachment with :checkhealth lsp.

What's included

Base: LazyVim with leader = <Space>, localleader = \, colorscheme catppuccin-mocha.

LazyVim extras enabled (in lua/config/lazy.lua): lang.go, lang.json, lang.yaml, lang.markdown, lang.typescript, lang.tailwind, dap.core.

Languages (LSP + Treesitter): Go, Zig, Lua, TypeScript/JavaScript, HTML, CSS, JSON, YAML, Markdown, SQL, Dockerfile, Python.

Concern Plugin / tool
LSP nvim-lspconfig + Mason (gopls, zls, lua_ls, ts_ls, html, cssls, jsonls, yamlls, marksman, sqlls, dockerls, pyright/ruff)
Completion blink.cmp (LazyVim default; SQL routed to dadbod)
Formatting conform.nvim via LazyVim's format pipeline
Debugging nvim-dap + delve (Go), codelldb (Zig/C/C++)
Testing neotest (Go, Python, Zig) with in-buffer pass/fail signs
Coverage nvim-coverage (Go)
Task running overseer.nvim (+ user templates)
AI chat opencode.nvim (provider-agnostic)
Database vim-dadbod + dadbod-ui + dadbod-completion
Git Neogit + diffview, plus LazyVim's lazygit
Explorer/picker snacks.nvim
Symbols aerial.nvim
Diagnostics trouble.nvim
Cheat sheet which-key.nvim (hold <leader>)

AI (opencode.nvim)

AI is intentionally environment-agnostic: opencode.nvim drives the external opencode CLI, so the model/provider (Anthropic, OpenAI, local models, etc.) is chosen in opencode's own config rather than here. Install the opencode CLI separately and configure your provider there.

Database (vim-dadbod)

Open the UI with <leader>Du. Add a connection with <leader>Da. Examples:

postgresql://user:pass@localhost:5432/dbname
mysql://user:pass@localhost:3306/dbname
sqlite:path/to/db.sqlite

SQL completion is provided via dadbod inside SQL buffers, and SQL autoformat-on-save is intentionally disabled (format manually with <leader>cf).

Key bindings

Hold <leader> (Space) to pop up the which-key menu — it lists every group below as a live cheat sheet. Mouse is enabled (mouse=a), and the explorer, dadbod UI, Neogit, DAP UI, trouble, aerial, and Overseer pickers are all clickable.

Note the deliberate capitalization: <leader>T* is Terminal (lowercase <leader>t* is the Test group), and <leader>D* is Database (lowercase <leader>d* is Debug).

AI (<leader>a)

Key Action
<leader>aa Ask AI about current context (n/v)
<leader>ax Ask AI about selection
<leader>at Toggle AI panel
go Operator: add range to AI chat
goo Add current line to AI chat
<S-C-u> / <S-C-d> Scroll AI chat up/down

Code Go (<leader>cg)

Key Action
<leader>cgb Run benchmarks (-bench=. -benchmem)
<leader>cgpc CPU profile
<leader>cgpm Memory profile
<leader>cgpt Trace profile

Code Zig (<leader>cz)

Key Action
<leader>czb zig build
<leader>czr zig build run
<leader>czt zig build test

Tests (neotest, <leader>t)

Works in Go, Python, and Zig buffers; results show as signs in the gutter.

Key Action
<leader>tt Run nearest test
<leader>tf Run test file
<leader>ts Toggle test summary
<leader>to Open test output
<leader>tc Show coverage (Go)

Debugging (DAP, <leader>d)

Go uses delve; Zig/C/C++ use codelldb. Zig launch configs build with debug symbols first, then run (Launch (zig build) prompts for the exe under zig-out/bin; Launch (current file) compiles the open file).

Key Action
<leader>db Toggle breakpoint
<leader>dB Conditional breakpoint
<leader>dc Continue / start
<leader>dC Run to cursor
<leader>di Step into
<leader>dO Step over
<leader>do Step out
<leader>dj / <leader>dk Stack down / up
<leader>dr Toggle REPL
<leader>ds Session
<leader>dt Terminate
<leader>dw Inspect widget (hover)
<leader>du Toggle DAP UI
<leader>de Eval (n/v)
<leader>dT Debug Go test
<leader>dL Debug last Go test

Tasks (Overseer, <leader>o)

Key Action
<leader>or Run a task (picker — includes go: and zig: templates)
<leader>ot Toggle task list

Database (<leader>D)

Key Action
<leader>Du Toggle DB UI
<leader>Da Add connection
<leader>Df Find DB buffer

Git (<leader>g)

Key Action
<leader>gg Lazygit (LazyVim default)
<leader>gn Neogit
<leader>gl Lazygit log
<leader>gf Lazygit file history

Search / Symbols (<leader>s)

Key Action
<leader>so Symbols outline (aerial)
<leader>sh Incoming calls
<leader>sc Outgoing calls

Diagnostics (Trouble, <leader>x)

Key Action
<leader>xx Diagnostics
<leader>xw Workspace diagnostics
<leader>xt TODOs

Terminal (<leader>T)

Key Action
<leader>Th Terminal (horizontal split)
<leader>Tv Terminal (vertical split)
<Esc><Esc> Exit terminal mode

Explorer & windows

Key Action
<C-e> Toggle explorer (snacks)
<C-S-v> / <C-v> Open file in vertical split
<C-S-h> / <C-x> Open file in horizontal split
<C-h/j/k/l> Navigate windows
<C-Up/Down/Left/Right> Resize window

Formatting (LazyVim pipeline)

Key / Command Action
<leader>cf Format buffer
<leader>uf Toggle autoformat (buffer)
<leader>uF Toggle autoformat (global)
:LazyFormat Format now

General editing

Key Action
<C-s> Save file
<S-h> / <S-l> Prev / next buffer
<Esc> Clear search highlight
<A-j> / <A-k> Move line/selection down/up
< / > (visual) Indent, keep selection

Formatters by file type

File type Formatter
Go gofumpt, goimports (-local github.com)
Lua stylua (2-space)
JS/TS/JSX/TSX prettier (2-space, single quotes)
HTML/CSS/SCSS prettier
JSON/JSONC/YAML prettier
Markdown prettier
SQL sql-formatter (postgresql; manual only)

File structure

~/.config/nvim/
├── init.lua                     # Entry point → require("config.lazy")
├── lua/
│   ├── config/
│   │   ├── lazy.lua             # lazy.nvim bootstrap, LazyVim + extras
│   │   ├── options.lua          # Neovim options
│   │   ├── keymaps.lua          # Custom keymaps
│   │   └── autocmds.lua         # Autocommands (yank hl, ft tweaks, SQL no-autoformat…)
│   ├── plugins/
│   │   ├── mason.lua            # Tooling installs (LSP/linters/formatters/DAP)
│   │   ├── lspconfig.lua        # Per-server LSP config (gopls, zls, …)
│   │   ├── treesitter.lua       # Parsers
│   │   ├── formatting.lua       # conform.nvim
│   │   ├── dap.lua              # Debugging (Go via delve, Zig via codelldb)
│   │   ├── neotest.lua          # Test runner (go/python/zig)
│   │   ├── go-coverage.lua      # Go coverage signs
│   │   ├── overseer.lua         # Task runner
│   │   ├── ai.lua               # opencode.nvim
│   │   ├── dadbod.lua           # Database
│   │   ├── git.lua              # Neogit + diffview
│   │   ├── editor.lua           # snacks tweaks + which-key groups
│   │   ├── symbols.lua          # aerial
│   │   ├── dashboard.lua        # trouble opts
│   │   ├── devcontainer.lua     # nvim-remote-containers
│   │   ├── performance.lua      # treesitter large-file guard
│   │   ├── theme.lua            # catppuccin
│   │   └── zig.lua              # Zig ft plugin (toolchain wired across files)
│   └── overseer/template/user/  # go_*, zig_{build,run,test} task templates

Zig notes

  • LSP is zls (lua/plugins/lspconfig.lua), root markers build.zig / build.zig.zon, with build-on-save and inlay hints.
  • zig build test and project-wide neotest runs require a standard test step in your build.zig; individual .zig files also work.
  • Debugging needs codelldb (:MasonInstall codelldb if it doesn't auto-install). Builds use -O Debug so symbols are present.

Troubleshooting

  • LSP not attaching: :checkhealth lsp — confirm the server appears and is attached (not just installed in Mason). If root_dir/root_markers look off, the server may not find your project root.
  • Formatting: :ConformInfo.
  • Tests not detected: ensure the Treesitter parser for the language is installed (:TSInstall <lang>); Zig needs a test step in build.zig.
  • Ctrl+Shift keys not firing: some terminals don't transmit them; use the plain-Ctrl fallbacks (<C-v> / <C-x> in the explorer).
  • Nerd Font icons missing: install a Nerd Font and set it in your terminal.

Known issues (in current repo)

Two unrelated typos exist in lua/config/keymaps.lua's opencode block (present before these docs): the scroll-up command string reads sesion.half.page.up (should be session.…), and <leader>at is mapped in t (terminal) mode where n/x is likely intended. Documented here for accuracy; fix when convenient.

Description
My own NVIM configuration
Readme Apache-2.0 157 KiB
Languages
Lua 100%