# Neovim Configuration
Personal Neovim 0.11 setup on macOS, based on [[kickstart.nvim]] and customized for Go development. Uses native LSP (`vim.lsp.config()`/`vim.lsp.enable()`), [[Catppuccin]] Mocha theme, and seamless [[Tmux Configuration|tmux]] integration.
Config directory: `~/.config/nvim/`
> [!info] Architecture Mental Model
> - `init.lua` is the single entry point — all options, keymaps, and plugins live here
> - **lazy.nvim** manages plugins (auto-installed to `~/.local/share/nvim/lazy/`)
> - **Mason** manages external tools (LSPs, formatters, linters, debuggers)
> - Kickstart plugins live in `lua/kickstart/plugins/` (debug, lint, indent, neo-tree, etc.)
> - Custom plugins live in `lua/custom/plugins/` (auto-imported by lazy.nvim)
> - Neovim 0.11 uses native `vim.lsp.config()` — no `lspconfig.setup()` needed
## Key Settings
| Setting | Value | Why |
|---------|-------|-----|
| Leader | `Space` | Central, easy to press |
| Line numbers | Relative | Easier jump motions (e.g., `5j`) |
| Mouse | Enabled | Resize splits, click panes |
| Clipboard | `unnamedplus` | Synced with OS clipboard |
| Update time | 250ms | Faster CursorHold events |
| Timeout | 300ms | Responsive key sequences |
| Splits | Right / below | Natural reading direction |
| Undo | Persistent (`undofile`) | Survives editor restarts |
| Search | Smart case | Lowercase = insensitive, uppercase = sensitive |
| Scrolloff | 10 lines | Cursor stays away from edges |
| Font | Nerd Font Mono | Icons in neo-tree, lualine, which-key |
## Cheat Sheet
### Leader Key Groups
Press `Space` and wait — **which-key** shows all available bindings.
| Prefix | Group | Description |
|--------|-------|-------------|
| `<leader>s` | `[S]earch` | Fuzzy find files, grep, help, keymaps |
| `<leader>t` | `[T]est / [T]oggle` | Run tests, toggle features |
| `<leader>h` | `Git [H]unk` | Stage/reset/preview hunks |
| `<leader>g` | `[G]it` | LazyGit and git operations |
| `<leader>d` | `[D]ebug` | DAP debugger controls |
### Search (fzf-lua)
| Keys | Action |
|------|--------|
| `<leader>sf` | Find files |
| `<leader>sg` | Live grep (search text in files) |
| `<leader>sh` | Search help tags |
| `<leader>sk` | Search keymaps |
| `<leader>sd` | Search diagnostics |
| `<leader>sr` | Resume last search |
| `<leader>sc` | Search commands |
| `<leader>s.` | Recent files |
| `<leader>sn` | Search Neovim config files |
| `<leader><leader>` | Switch between open buffers |
| `<leader>/` | Fuzzy search in current buffer |
### LSP (Language Server)
| Keys | Action |
|------|--------|
| `grn` | Rename symbol |
| `gra` | Code action |
| `grr` | Find references (fzf picker) |
| `grd` | Go to definition (fzf picker) |
| `gri` | Go to implementation (fzf picker) |
| `grt` | Go to type definition (fzf picker) |
| `grD` | Go to declaration |
| `gO` | Document symbols |
| `gW` | Workspace symbols |
| `K` | Hover documentation (built-in) |
| `<leader>th` | Toggle inlay hints |
> [!tip] Neovim 0.11 Built-in LSP Keymaps
> `grn`, `grr`, `gra`, `gri` are now native Neovim defaults (no plugin needed).
> fzf-lua overrides `grr`, `gri`, `grd` to show results in an fzf picker.
### Navigation
| Keys | Action |
|------|--------|
| `Ctrl+h/j/k/l` | Navigate panes (tmux-aware) |
| `<leader>e` | Toggle neo-tree file explorer |
| `\` | Toggle neo-tree (alternative) |
| `[d` / `]d` | Previous / next diagnostic |
| `<leader>q` | Open diagnostic quickfix list |
| `<Esc>` | Clear search highlights |
### File Explorer (neo-tree)
| Keys | Action |
|------|--------|
| `<leader>e` | Toggle file tree |
| `a` | Add file/directory |
| `d` | Delete |
| `r` | Rename |
| `c` | Copy |
| `m` | Move |
| `y` | Copy name |
| `Y` | Copy path |
| `/` | Filter |
### Testing (neotest)
| Keys | Action |
|------|--------|
| `<leader>tt` | Run nearest test |
| `<leader>tf` | Run all tests in file |
| `<leader>ts` | Toggle test summary panel |
| `<leader>to` | Toggle test output panel |
> [!note] Go tests run with `-race -count=1 -v` flags by default.
### Debugging (nvim-dap)
| Keys | Action |
|------|--------|
| `F5` | Start / continue |
| `F10` | Step over |
| `F11` | Step into |
| `F12` | Step out |
| `<leader>db` | Toggle breakpoint |
| `<leader>dB` | Set conditional breakpoint |
> [!note] Delve is the Go debugger backend. Installed automatically via Mason.
### Git (gitsigns + lazygit)
| Keys | Action |
|------|--------|
| `<leader>gg` | Open LazyGit (full TUI) |
| `<leader>hs` | Stage hunk |
| `<leader>hr` | Reset hunk |
| `<leader>hp` | Preview hunk |
| `<leader>hb` | Blame line |
| `]c` / `[c` | Next / previous hunk |
### Editing Helpers
| Keys | Action |
|------|--------|
| `<leader>f` | Format buffer |
| `saiw)` | Surround word with parentheses (mini.surround) |
| `sd'` | Delete surrounding quotes |
| `sr)'` | Replace surrounding ) with ' |
| `va)` | Select around parentheses (mini.ai) |
| `yinq` | Yank inside next quote |
### Completion (blink.cmp)
| Keys | Action |
|------|--------|
| `Ctrl+y` | Accept completion |
| `Ctrl+n` / `Ctrl+p` | Next / previous item |
| `Ctrl+Space` | Open completion menu |
| `Ctrl+e` | Dismiss menu |
| `Ctrl+k` | Toggle signature help |
| `Tab` / `Shift+Tab` | Navigate snippet fields |
## Installed Plugins (33)
### Core
| Plugin | Purpose |
|--------|---------|
| `lazy.nvim` | Plugin manager (auto-install, lazy-loading) |
| `nvim-lspconfig` | LSP client configuration |
| `mason.nvim` | External tool installer (LSPs, formatters, linters) |
| `mason-tool-installer` | Auto-install tools on startup |
| `blink.cmp` | Autocompletion engine |
| `LuaSnip` | Snippet engine |
| `nvim-treesitter` | Syntax highlighting and code understanding |
### Navigation & Search
| Plugin | Purpose |
|--------|---------|
| `fzf-lua` | Fuzzy finder (files, grep, LSP, commands) |
| `neo-tree.nvim` | File explorer sidebar |
| `which-key.nvim` | Keymap hints popup |
| `vim-tmux-navigator` | Seamless `Ctrl+h/j/k/l` across Neovim and tmux |
### Go Development
| Plugin | Purpose |
|--------|---------|
| `neotest` + `neotest-golang` | Test runner with `-race` flag |
| `nvim-dap` + `nvim-dap-go` | Debugger (Delve) |
| `conform.nvim` | Format-on-save (goimports + gofumpt) |
| `nvim-lint` | Linter integration (golangci-lint) |
### UI & Theme
| Plugin | Purpose |
|--------|---------|
| `catppuccin/nvim` | Catppuccin Mocha colorscheme |
| `lualine.nvim` | Statusline (mode, branch, diagnostics) |
| `gitsigns.nvim` | Git signs in gutter, hunk operations |
| `indent-blankline.nvim` | Visual indent guides |
| `fidget.nvim` | LSP progress indicator |
| `todo-comments.nvim` | Highlight TODO/FIXME/NOTE in comments |
### Editing
| Plugin | Purpose |
|--------|---------|
| `mini.ai` | Enhanced around/inside text objects |
| `mini.surround` | Add/delete/replace surroundings |
| `nvim-autopairs` | Auto-close brackets and quotes |
| `guess-indent.nvim` | Auto-detect indentation |
## Go Tooling Stack
Installed automatically via Mason on first open of a `.go` file:
| Tool | Purpose |
|------|---------|
| `gopls` | Go language server (completion, diagnostics, refactoring) |
| `goimports` | Import organizer (adds missing, removes unused) |
| `gofumpt` | Stricter Go formatter (superset of gofmt) |
| `golangci-lint` | Meta-linter (runs many linters in parallel) |
| `delve` | Go debugger |
| `impl` | Generate interface method stubs |
| `gomodifytags` | Add/modify struct field tags |
### gopls Configuration
| Feature | Setting |
|---------|---------|
| Static analysis | unusedparams, shadow, nilness, unusedwrite, useany |
| Staticcheck | Enabled |
| Formatter | gofumpt |
| Imports | completeUnimported, auto-import |
| Placeholders | Enabled (function params) |
| Code lenses | gc_details, generate, test, tidy |
| Inlay hints | All types enabled (toggle with `<leader>th`) |
| Semantic tokens | Enabled |
## File Structure
```
~/.config/nvim/
├── init.lua # Main config (options, keymaps, plugins)
├── lua/
│ ├── kickstart/
│ │ └── plugins/
│ │ ├── debug.lua # nvim-dap + nvim-dap-go (Delve)
│ │ ├── indent_line.lua # indent-blankline
│ │ ├── lint.lua # nvim-lint (golangci-lint for Go)
│ │ ├── autopairs.lua # auto-close brackets
│ │ ├── neo-tree.lua # file explorer
│ │ └── gitsigns.lua # git gutter signs
│ └── custom/
│ └── plugins/
│ ├── tmux-navigator.lua # Ctrl+h/j/k/l across nvim/tmux
│ ├── neotest.lua # test runner (Go with -race)
│ ├── lazygit.lua # LazyGit floating window
│ └── statusline.lua # lualine with Catppuccin
└── lazy-lock.json # Plugin version lock file
```
## Common Workflows
### Open a Go project
```bash
cd ~/projects/myapp
nvim .
```
neo-tree opens on the left (`<leader>e`). gopls starts automatically. Mason installs missing tools on first run.
### Find and navigate code
```
<leader>sf # find a file by name
<leader>sg # search text across all files
grd # jump to definition of symbol under cursor
grr # find all references
gO # browse document symbols
```
### Run tests
```
<leader>tt # run the test under cursor
<leader>tf # run all tests in file
<leader>ts # open test summary panel
<leader>to # open test output
```
### Debug a test
```
<leader>db # set breakpoint on current line
<leader>tt # run nearest test (or F5 to start debugger)
F10 # step over
F11 # step into
F5 # continue
```
### Git workflow
```
<leader>gg # open LazyGit for staging, committing, pushing
<leader>hp # preview a changed hunk inline
<leader>hs # stage a hunk
<leader>hr # reset a hunk
```
## Verification Commands
```bash
# Check Neovim version
nvim --version | head -1
# Check plugin status
nvim -c ':Lazy'
# Check Mason tool status
nvim -c ':Mason'
# Run health check
nvim -c ':checkhealth'
# List installed plugins
ls ~/.local/share/nvim/lazy/
# List installed treesitter parsers
ls ~/.local/share/nvim/lazy/nvim-treesitter/parser/
```
## Tmux Integration
The `vim-tmux-navigator` plugin is installed on both sides:
- **Neovim**: `lua/custom/plugins/tmux-navigator.lua`
- **tmux**: `set -g @plugin 'christoomey/vim-tmux-navigator'` in `~/.tmux.conf`
`Ctrl+h/j/k/l` moves seamlessly between Neovim splits and tmux panes. You never need to think about which one you are in.
## Theme Consistency
==Catppuccin Mocha== is configured across all three tools:
- **[[Ghostty Configuration|Ghostty]]**: `theme = Catppuccin Mocha` in `~/.config/ghostty/config`
- **[[Tmux Configuration|tmux]]**: `@catppuccin_flavor 'mocha'` in `~/.tmux.conf`
- **Neovim**: `flavour = 'mocha'` in `init.lua` with integrations for all plugins