Skip to content

Bullish-Design/nixvim

Repository files navigation

nix_neovim_v2

A minimal, coherent, production-ready Neovim configuration for NixOS and Home Manager. Built on mini.nvim with a "one tool per task" philosophy.

Philosophy

This configuration follows three core principles:

  1. Minimal - Only essential tools. One plugin per task.
  2. Coherent - Clear, interconnected modules. Easy to understand and extend.
  3. mini.nvim-first - Uses mini.nvim's lightweight, focused ecosystem for UI, navigation, and sessions.

Three-Tier Architecture

  • Tier 1 (Builtins) - Neovim's builtin LSP, diagnostics, terminal, DAP
  • Tier 2 (mini.nvim) - UI (clue, notify), navigation (pick, files), sessions
  • Tier 3 (Specialized) - Language tools, formatters, linters, git integration

Features

Feature Tool Included
UI and Navigation mini.nvim (clue, pick, files, notify) Yes
Code Completion nvim-cmp with nvim-lspconfig Yes
Formatting conform-nvim Yes
Linting nvim-lint Yes
Debugging nvim-dap and nvim-dap-ui Yes
Testing neotest (Python, Rust, Vitest) Yes
Git gitsigns, neogit, diffview Yes
Syntax Highlighting nvim-treesitter with context Yes
Terminal Builtin (no plugin) Yes
Sessions mini.sessions Yes

Installation

Prerequisites

  • NixOS or Home Manager (Linux/macOS)
  • Flakes enabled (experimental-features = nix-command flakes)
  • Neovim 0.11+ (automatically installed via Nix)

Option 1: Standalone (Temporary)

Test the configuration without modifying your system:

cd /path/to/nix_neovim_v2
nix flake show
nix flake develop
nvim --version

Option 2: Home Manager (Permanent)

Add to your Home Manager configuration:

{
  imports = [
    nix-neovim-v2.homeManagerModules.default
  ];

  home.stateVersion = "23.11";
}

Then apply:

home-manager switch --flake ".#your-host"

Testing in Neovim

This section guides you through testing all configuration features.

Setup

cd /home/andrew/Documents/Projects/IDE/nix_neovim_v2
nix develop

This provides Neovim 0.11+, all LSP servers, formatters, linters, and test runners.

Phase 1: Startup and Basic Navigation (5 minutes)

Start Neovim:

nvim

Verify that it starts without errors. Check:

  • Status line appears at the bottom
  • No error messages or red highlights
  • No diagnostic markers in the gutter

Test basic keybindings:

Key Action Expected
<space> Show available commands Menu appears with key hints
<C-s> Save File is written
<leader>h Clear search highlight Highlights disappear
<leader>q Quit Neovim exits

Phase 2: File Navigation (5 minutes)

Test file finding and buffer switching:

Key Action Test
<leader>ff Find files Type "README", should show README.md
<leader>fg Live grep Type "mini", shows matching lines
<leader>fb Find buffers Shows open buffers
<leader>e Toggle file explorer Opens/closes sidebar

In the file explorer:

  1. Press <leader>e to open
  2. Navigate to nvim directory
  3. Press Enter to expand
  4. Find init.lua and open it
  5. Press <leader>e again to close

Phase 3: LSP and Code Completion (8 minutes)

Create a test file:

# In Neovim:
:e test.lua

Type this code with an intentional error:

local function greet(name)
  print("Hello " .. nam)  -- typo: 'nam' instead of 'name'
end

greet("World")

Save the file:

:w test.lua

Check for diagnostics:

  • A red underline appears under nam
  • The line number shows "E" in the gutter

Test diagnostic navigation:

Key Action
]d Jump to next error
[d Jump to previous error
<leader>x Open quickfix list

Test code completion:

  1. Position cursor after the opening parenthesis: greet(
  2. Press <C-n> to trigger completion
  3. A menu should appear with available variables
  4. Use arrow keys to navigate and Enter to select

Fix the typo:

  • Change nam to name
  • Save the file with <C-s>
  • The error should disappear

Clean up:

:bd test.lua

Phase 4: Terminal Integration (3 minutes)

Test the terminal toggle:

Key Action
<A-i> Toggle terminal

Test sequence:

  1. Press <A-i> to open the terminal at the bottom (15 lines)
  2. Type: echo "Hello from terminal"
  3. Press Enter - the command executes
  4. Press <A-i> to close the terminal
  5. Press <A-i> again - the terminal reopens with history preserved

Phase 5: Git Integration (5 minutes)

Open a file in this git repository:

# In Neovim:
:e nvim/lua/config/options.lua

Check for git gutter signs:

  • Look at the left edge (sign column)
  • Changed lines show (pipe)
  • Deleted lines show _
  • Top-deleted lines show

Test git keybindings:

Key Action
]h Next hunk
[h Previous hunk
<leader>gp Preview hunk (shows diff)
<leader>gb Show blame for current line
<leader>gd Show diff for current file

Test hunk operations:

  1. Position cursor in a changed hunk
  2. Press <leader>gs to stage the hunk
  3. Press <leader>gu to undo staging

Phase 6: Session Management (3 minutes)

Test saving and restoring sessions:

1. Open multiple files:
   :e nvim/lua/config/options.lua
   :e nvim/lua/config/keymaps.lua

2. Navigate to specific lines in each file

3. Save session:
   <leader>qs

4. Quit Neovim:
   <leader>qq

5. Restart:
   nvim

6. Restore session:
   <leader>qr
   Select the session from the picker

Verify:

  • All files reopen
  • Cursor positions are preserved
  • Window layout is restored

Phase 7: UI Toggles (3 minutes)

Test runtime configuration toggles:

Key Action
<leader>ul Toggle line numbers
<leader>ur Toggle relative numbers
<leader>uw Toggle word wrap
<leader>uh Toggle inlay hints
<leader>uf Toggle format on save

Each toggle should take effect immediately without requiring a restart.

Phase 8: Formatting and Linting (5 minutes)

Create a test file:

# In Neovim:
:e test_format.py

Type poorly formatted code:

def hello(  x,y  ):
    return x+y

Test auto-formatting:

  1. Save with <C-s>
  2. The code should reformat automatically
  3. If it doesn't, verify formatting is enabled: <leader>uf (should show "enabled")

Test linting:

  1. Add an unused import: import os
  2. Save the file
  3. A diagnostic marker should appear on the import line
  4. Open the quickfix list with <leader>x to see all linting errors

Clean up:

:bd test_format.py

Phase 9: Debugging (Python Example) (5 minutes)

Create a test script:

# In Neovim:
:e test_debug.py

Type this code:

def add(a, b):
    result = a + b  # We'll break here
    return result

print(add(2, 3))

Test breakpoints and debugging:

  1. Position cursor on the result = a + b line
  2. Press <leader>db to set a breakpoint
  3. Press <leader>dc to start debugging
  4. The debugger should pause at the breakpoint
  5. The DAP UI panel should open showing local variables

Test stepping:

Key Action
<leader>dO Step over (execute current line)
<leader>di Step into (enter function)
<leader>do Step out (exit function)
<leader>dt Terminate debug session

View variables:

  • Look at the DAP UI panel on the left
  • Local variables (a, b, result) should be visible

Clean up:

:bd test_debug.py

Note: DAP setup requires language-specific adapters. Python uses debugpy (installed). Rust and C/C++ use lldb. Other languages may need additional configuration.

Phase 10: Testing (5 minutes)

Create a test file:

# In Neovim:
:e test_sample.py

Type these tests:

def test_addition():
    assert 2 + 2 == 4

def test_failure():
    assert 1 + 1 == 3  # This will fail

Run tests:

Key Action
<leader>tt Run all tests in file
<leader>tr Run test under cursor
<leader>ts Toggle test summary
<leader>to Toggle test output

Check results:

  • Passing tests show with a check mark
  • Failing tests show with an X
  • Output panel shows detailed results

Clean up:

:bd test_sample.py

Phase 11: Obsidian Integration (Optional) (3 minutes)

If you have an Obsidian vault:

:ObsidianOpen

This opens your configured Obsidian vault. You can also create new notes with:

:ObsidianNew NoteName

Configuration Structure

nix_neovim_v2/
├── flake.nix                    # Flake inputs and outputs
├── hm-module.nix                # Home Manager module
├── plugins.nix                  # Plugin list
├── nvim/
│   ├── init.lua                 # Entry point
│   ├── lua/
│   │   ├── config/
│   │   │   ├── init.lua         # Loader
│   │   │   ├── options.lua      # Vim options
│   │   │   ├── keymaps.lua      # Keybindings
│   │   │   └── autocmds.lua     # Auto-commands
│   │   └── plugins/
│   │       ├── init.lua         # Loader
│   │       ├── lsp.lua          # LSP configuration
│   │       ├── format.lua       # Formatting configuration
│   │       ├── lint.lua         # Linting configuration
│   │       ├── mini.lua         # Mini.nvim modules
│   │       ├── git.lua          # Git integration
│   │       ├── dap.lua          # Debugging configuration
│   │       ├── test.lua         # Testing configuration
│   │       ├── treesitter.lua   # Syntax highlighting
│   │       ├── tools.lua        # Additional tools
│   │       └── codecompanion.lua # AI companion
│   └── plugins/                 # Mini.nvim specs
├── README.md                    # This file
└── ARCHITECTURE.md              # Design documentation

Keybindings Reference

Core Navigation

Key Action
<leader>ff Find files
<leader>fg Live grep
<leader>fb Find buffers
<leader>fr Recent files
<leader>e Toggle file explorer

Editing

Key Action
<C-s> Save
<C-d> Half-page down (centered)
<C-u> Half-page up (centered)

LSP and Diagnostics

Key Action
[d Previous diagnostic
]d Next diagnostic
<leader>x Diagnostics to quickfix
<leader>uh Toggle inlay hints

Git

Key Action
]h Next hunk
[h Previous hunk
<leader>gs Stage hunk
<leader>gr Reset hunk
<leader>gp Preview hunk
<leader>gb Blame line
<leader>gd Diff (working)
<leader>gD Diff (cached)

Debug

Key Action
<leader>db Toggle breakpoint
<leader>dc Continue
<leader>di Step into
<leader>do Step out
<leader>dO Step over
<leader>dt Terminate

Testing

Key Action
<leader>tt Run file tests
<leader>tr Run nearest test
<leader>ts Toggle summary
<leader>to Toggle output

Sessions

Key Action
<leader>qs Save session
<leader>qr Restore session
<leader>qq Quit all

UI Toggles

Key Action
<leader>ul Toggle line numbers
<leader>ur Toggle relative numbers
<leader>uw Toggle word wrap
<leader>uh Toggle inlay hints
<leader>uf Toggle format on save

Terminal

Key Action
<A-i> Toggle terminal

Included Language Servers

Language Server
Lua lua-language-server
Rust rust-analyzer
Python pyright
Go gopls
TypeScript/JavaScript typescript-language-server
Bash bash-language-server
Nix nil
C/C++ clangd

Customization

Add a Custom Keybinding

Edit nvim/lua/config/keymaps.lua:

local map = vim.keymap.set

map("n", "<leader>mc", function()
  print("Custom command!")
end, { desc = "My custom command" })

Change Options

Edit nvim/lua/config/options.lua:

local opt = vim.opt

opt.tabstop = 2
opt.shiftwidth = 2
opt.expandtab = true

Add a Plugin

  1. Add to plugins.nix:
vp.your-plugin-name
  1. Create nvim/lua/plugins/your-plugin.lua:
require("your-plugin").setup({
  -- options
})
  1. Import in nvim/lua/plugins/init.lua:
require("plugins.your-plugin")

Add a Language Server

  1. Add package to hm-module.nix:
your-language-server
  1. Configure in nvim/lua/plugins/lsp.lua:
vim.lsp.config("your-server", {
  on_attach = on_attach,
  settings = { }
})
vim.lsp.enable("your-server")

Troubleshooting

Neovim won't start with "E5108: Error executing lua"

Look at the line number in the error. Usually indicates a typo in a config file.

Validate Lua syntax:

luacheck nvim/lua/config/options.lua

LSP not starting

Check which servers are enabled in nvim/lua/plugins/lsp.lua.

Verify installation:

lua-language-server --version
pyright --version
rust-analyzer --version

Diagnostics not showing

Try enabling virtual text:

:lua vim.diagnostic.config({ virtual_text = true })

Colors look wrong

Try enabling true color support:

:set termguicolors

Plugins not loading

The flake may be out of sync:

nix flake update
nix flake develop

Further Reading

License

This configuration is provided as-is. Feel free to fork, modify, and adapt.

Status

Production-ready. All 31 critical issues have been fixed and verified.

See ARCHITECTURE.md for design documentation.

About

A Neovim configuration for use with NixOS, Home-Manager, and Flakes

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors