A modular Neovim configuration optimized for C# development using roslyn.nvim, with support for Blazor/Razor files.
~/.config/nvim/
├── init.lua
├── lua/
│ ├── config/
│ │ ├── options.lua # Editor settings
│ │ ├── keymaps.lua # Space as leader + keybindings
│ │ └── lazy.lua # Plugin manager bootstrap
│ └── plugins/
│ ├── colorscheme.lua # Tokyonight theme
│ ├── treesitter.lua # C# + Razor syntax
│ ├── mason.lua # Tool installer
│ ├── lsp.lua # roslyn.nvim + rzls.nvim
│ ├── cmp.lua # Autocompletion
│ ├── fzf.lua # Fuzzy finding
│ ├── dap.lua # .NET debugging
│ └── neotest.lua # Unit testing
- LSP: Full C# language server via roslyn.nvim with inlay hints
- Razor Support: Blazor/Razor development via rzls.nvim
- Debugging: .NET debugging with netcoredbg
- Unit Testing: Test runner with neotest-dotnet
- Autocompletion: nvim-cmp with LSP integration
- Syntax Highlighting: Treesitter for C#, Razor, and more
- Fuzzy Finding: fzf-lua for file/text searching
- Theme: Tokyonight colorscheme
-
Start Neovim (lazy.nvim will auto-install plugins):
nvim
-
Install Mason tools:
:MasonInstall roslyn rzls
-
Verify installation:
:checkhealth
- Neovim >= 0.10.0
- .NET SDK (9.0+)
- Git, ripgrep, fzf (for fuzzy finding)
- Node.js and npm (for some LSP features)
| Key | Action |
|---|---|
<Space> |
Leader key |
<leader>w |
Save file |
<leader>q |
Quit |
<leader>x |
Save and quit |
<Esc> |
Clear search highlights |
| Key | Action |
|---|---|
<C-h> |
Move to left window |
<C-j> |
Move to bottom window |
<C-k> |
Move to top window |
<C-l> |
Move to right window |
<S-h> |
Previous buffer |
<S-l> |
Next buffer |
| Key | Action |
|---|---|
<leader>ff |
Find files |
<leader>fg |
Live grep |
<leader>fb |
Find buffers |
<leader>fh |
Help tags |
<leader>fo |
Recent files |
<leader>fc |
Commands |
<leader>fk |
Keymaps |
| Key | Action |
|---|---|
gd |
Go to definition |
gD |
Go to declaration |
gr |
Show references |
gi |
Go to implementation |
K |
Hover documentation |
<leader>ca |
Code action |
<leader>rn |
Rename symbol |
<leader>d |
Show diagnostics |
[d |
Previous diagnostic |
]d |
Next diagnostic |
| Key | Action |
|---|---|
<F5> |
Continue / Start debugging |
<F9> |
Toggle breakpoint |
<F10> |
Step over |
<F11> |
Step into |
<F8> |
Step out |
<leader>dr |
Open REPL |
<leader>dl |
Run last |
<leader>dt |
Debug nearest test |
| Key | Action |
|---|---|
<leader>tr |
Run nearest test |
<leader>tf |
Run test file |
<leader>ta |
Run all tests in solution |
<leader>ts |
Toggle test summary |
<leader>to |
Show test output |
<leader>dt |
Debug nearest test |
| Key | Action |
|---|---|
<C-Space> |
Trigger completion |
<CR> |
Confirm selection |
<Tab> |
Next item / Expand snippet |
<S-Tab> |
Previous item |
<C-b> |
Scroll docs up |
<C-f> |
Scroll docs down |
<C-e> |
Abort completion |
cd ~/projects
dotnet new console -n MyApp
cd MyApp
dotnet build
nvim- Build your project:
dotnet build - Open a C# file in Neovim
- Set a breakpoint with
F9 - Start debugging with
F5 - You'll be prompted for the path to the DLL (usually in
bin/Debug/net9.0/)
- Open a test file
- Position cursor on a test method
- Run with
<leader>tror debug with<leader>dt
All plugin configurations are modular and can be customized by editing files in lua/plugins/.
Edit lua/config/options.lua to modify:
- Tab size (default: 4 spaces)
- Line numbers
- Search settings
- And more
Edit lua/config/keymaps.lua to add your own keybindings.
Create a new file in lua/plugins/ with your plugin configuration:
return {
"author/plugin-name",
config = function()
-- Plugin setup here
end,
}- Check if roslyn is installed:
:Mason - Check LSP status:
:LspInfo - Check health:
:checkhealth
- Ensure netcoredbg is installed:
:Mason - Verify .NET SDK is installed:
dotnet --version - Check DAP configuration:
:lua print(vim.inspect(require('dap').configurations.cs))
If roslyn or rzls fail to install, ensure the custom registry is configured in lua/plugins/mason.lua:
registries = {
"github:mason-org/mason-registry",
"github:Crashdummyy/mason-registry",
}