This guide describes how to integrate .NET Core debugging in Neovim using nvim-dap and netcoredbg.
To start debugging do the following. Ensure you have configured the code below
Dont start the project before doing this, debugger has to start it for you
- Open any
.csfile in the project - Set a breakpoint with
<leader>b - Press
<F5> - Select the project you want to debug (if your breakpoint is in a library you have to select the entry point project)
- Wait for breakpoint to be hit
- You can now
<F10>step over,<F11>step into,<F5>continue and more (see code)
In the DAP REPL, assignment expressions like x = 5 reassign the variable in the current stack frame.
--lazy.nvim
--nvim-dap config
return {
"mfussenegger/nvim-dap",
config = function()
local dap = require "dap"
-- Keymaps for controlling the debugger
vim.keymap.set("n", "q", function()
dap.terminate()
dap.clear_breakpoints()
end, { desc = "Terminate and clear breakpoints" })
vim.keymap.set("n", "<F5>", dap.continue, { desc = "Start/continue debugging" })
vim.keymap.set("n", "<F10>", dap.step_over, { desc = "Step over" })
vim.keymap.set("n", "<F11>", dap.step_into, { desc = "Step into" })
vim.keymap.set("n", "<F12>", dap.step_out, { desc = "Step out" })
vim.keymap.set("n", "<leader>b", dap.toggle_breakpoint, { desc = "Toggle breakpoint" })
vim.keymap.set("n", "<leader>dO", dap.step_over, { desc = "Step over (alt)" })
vim.keymap.set("n", "<leader>dC", dap.run_to_cursor, { desc = "Run to cursor" })
vim.keymap.set("n", "<leader>dr", dap.repl.toggle, { desc = "Toggle DAP REPL" })
vim.keymap.set("n", "<leader>dj", dap.down, { desc = "Go down stack frame" })
vim.keymap.set("n", "<leader>dk", dap.up, { desc = "Go up stack frame" })
end
}easy-dotnet fully supports interactive console debugging (e.g., Console.ReadLine()). You can control where your target application runs using the debugger.console option in your easy-dotnet setup:
integratedTerminal(Default): Runs the application inside a Neovim buffer or thenvim-dap-uiconsole widget. This keeps everything inside your editor and prevents your application's standard output from cluttering the DAP REPL.externalTerminal: Spawns a completely detached OS terminal window (similar to hitting F5 in Visual Studio).
If you choose to use an externalTerminal, you must tell nvim-dap which terminal emulator to use on your machine. You can configure this globally in your Neovim configuration:
local dap = require("dap")
-- Windows Terminal (Windows)
dap.defaults.fallback.external_terminal = {
command = "wt",
args = { "-w", "0", "nt", "--" },
}
-- Kitty (Linux/macOS)
dap.defaults.fallback.external_terminal = {
command = "kitty",
args = { "--hold" },
}
-- Alacritty (Linux/macOS)
dap.defaults.fallback.external_terminal = {
command = "alacritty",
args = { "-e" },
}
You can bind a key just like <F5> / Run in Visual Studio that triggers debugging for the default project or a selected profile.
vim.keymap.set("n", "<C-p>", function()
vim.cmd "Dotnet debug default profile"
end, { nowait = true, desc = "Start debugging" })easy-dotnet.nvim provides real-time performance monitoring during debug sessions through two custom dapui widgets: easy-dotnet_cpu and easy-dotnet_mem. These widgets display live CPU usage (percentage) and memory consumption (bytes) of your debugged application.
- CPU Widget: Shows real-time CPU percentage utilization
- Memory Widget: Displays current memory usage in bytes
- Live Updates: Automatically refreshes during active debug sessions
Add the widgets to your dapui layout configuration:
local dapui = require("dapui")
dapui.setup {
layouts = {
{
elements = {
{ id = "easy-dotnet_cpu", size = 0.5 }, -- CPU usage panel (50% of layout)
{ id = "easy-dotnet_mem", size = 0.5 }, -- Memory usage panel (50% of layout)
},
size = 35, -- Width of the sidebar
position = "right",
},
},
}The widgets integrate seamlessly into your debug UI, providing at-a-glance performance metrics: