No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-07-04 15:49:12 +02:00
README.md update readme 2026-07-04 15:49:12 +02:00

Neovim + C#: Debugging | with user input

The Problem

A C# console application (e.g. .NET / dotnet run) that reads from standard input using Console.ReadLine();

When the app reaches a ReadLine(), it hangs forever, because theres no terminal attached to provide user input while the debugger is running.

Create the Test Project

cd ~/Documents && \
dotnet new console -n MyConsole && \
cd MyConsole && \
dotnet build

Program.cs

Console.Write("Enter your name: ");

string name = Console.ReadLine();

Console.WriteLine($"Hello, {name}!"); // breakpoint here
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();

Run in symbolized DLL

First we need to build the debug version so we get the symbols

dotnet build -c Debug

Then we need to run the symbolized DLL

dotnet run --no-build --configuration Debug

Configure nvim

we need to tell nvim to send an attach request instead of a launch request in order to attach to the running process

-- lua/custom-config/nvim-dap.lua

-- ...

dap.configurations.cs = {
  -- {
  --   type = "coreclr",
  --   name = "LAUNCH directly from nvim",
  --   request = "launch",
  --   program = function()
  --     return require("dap-dll-autopicker").build_dll_path()
  --   end
  -- },
  {
    type = "coreclr",
    name = "ATTACH to running app in dedicated terminal",
    request = "attach",
    processId = function()
      return require("dap.utils").pick_process()
    end,
  }
}

you can also bind keys directly to a specific configuration...

local dap = require("dap")

-- Normal launch (build + run under debugger)
vim.keymap.set("n", "<F5>", function()
  dap.run(dap.configurations.cs[1])
end, { desc = "DAP: Launch" })

-- Attach to already running process (for console apps)
vim.keymap.set("n", "<F6>", function()
  dap.run(dap.configurations.cs[2])
end, { desc = "DAP: Attach" })

But I'd rather just pick the configuration when needed

Debugging workflow

Follow this procedure from top to bottom:

  1. nvim - set breakpoint
  2. terminal - dotnet build -c Debug
  3. terminal - dotnet run --no-build --configuration Debug
  4. nvim - F5 - :lua require('dap').continue(), pick with fzf
  5. terminal - do your input
  6. nvim - breakpoint should hit

The sequence diagram can be found here.