From a18d7270b6174acc4b6455e480c292c88b7932c5 Mon Sep 17 00:00:00 2001 From: Jesper Liljegren Date: Thu, 26 Mar 2026 09:22:56 +0100 Subject: [PATCH] Revert "feat: add .NET development plugins and improve LSP navigation fallbacks" This reverts commit 20b41844decb19a399b35a9461046c3a64c066fc. --- init.lua | 58 +--- lua/custom/plugins/dotnet.lua | 486 ---------------------------------- 2 files changed, 8 insertions(+), 536 deletions(-) delete mode 100644 lua/custom/plugins/dotnet.lua diff --git a/init.lua b/init.lua index 4e81bfc1..8da2a65e 100644 --- a/init.lua +++ b/init.lua @@ -416,15 +416,6 @@ require('lazy').setup({ group = vim.api.nvim_create_augroup('telescope-lsp-attach', { clear = true }), callback = function(event) local buf = event.buf - local client = vim.lsp.get_client_by_id(event.data.client_id) - - local goto_declaration = function() - if client and client:supports_method('textDocument/declaration', buf) then - vim.lsp.buf.declaration() - else - builtin.lsp_definitions() - end - end -- Find references for the word under your cursor. vim.keymap.set('n', 'grr', builtin.lsp_references, { buffer = buf, desc = '[G]oto [R]eferences' }) @@ -436,9 +427,7 @@ require('lazy').setup({ -- Jump to the definition of the word under your cursor. -- This is where a variable was first declared, or where a function is defined, etc. -- To jump back, press . - vim.keymap.set('n', 'gd', builtin.lsp_definitions, { buffer = buf, desc = '[G]oto [D]efinition' }) vim.keymap.set('n', 'grd', builtin.lsp_definitions, { buffer = buf, desc = '[G]oto [D]efinition' }) - vim.keymap.set('n', 'gD', goto_declaration, { buffer = buf, desc = '[G]oto [D]eclaration' }) -- Fuzzy find all the symbols in your current document. -- Symbols are things like variables, functions, types, etc. @@ -491,15 +480,7 @@ require('lazy').setup({ -- Automatically install LSPs and related tools to stdpath for Neovim -- Mason must be loaded before its dependents so we need to set it up here. -- NOTE: `opts = {}` is the same as calling `require('mason').setup({})` - { - 'mason-org/mason.nvim', - opts = { - registries = { - 'github:mason-org/mason-registry', - 'github:Crashdummyy/mason-registry', - }, - }, - }, + { 'mason-org/mason.nvim', opts = {} }, { 'mason-org/mason-lspconfig.nvim', opts = {} }, 'WhoIsSethDaniel/mason-tool-installer.nvim', @@ -542,8 +523,6 @@ require('lazy').setup({ vim.api.nvim_create_autocmd('LspAttach', { group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }), callback = function(event) - local client = vim.lsp.get_client_by_id(event.data.client_id) - -- NOTE: Remember that Lua is a real programming language, and as such it is possible -- to define small helper and utility functions so you don't have to repeat yourself. -- @@ -558,28 +537,20 @@ require('lazy').setup({ -- Most Language Servers support renaming across files, etc. map('grn', vim.lsp.buf.rename, '[R]e[n]ame') - -- Show documentation for the symbol under your cursor. - map('K', vim.lsp.buf.hover, 'Hover Documentation') - -- Execute a code action, usually your cursor needs to be on top of an error -- or a suggestion from your LSP for this to activate. map('gra', vim.lsp.buf.code_action, '[G]oto Code [A]ction', { 'n', 'x' }) -- WARN: This is not Goto Definition, this is Goto Declaration. -- For example, in C this would take you to the header. - map('grD', function() - if client and client:supports_method('textDocument/declaration', event.buf) then - vim.lsp.buf.declaration() - else - vim.lsp.buf.definition() - end - end, '[G]oto [D]eclaration') + map('grD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') -- The following two autocommands are used to highlight references of the -- word under your cursor when your cursor rests there for a little while. -- See `:help CursorHold` for information about when this is executed -- -- When you move your cursor, the highlights will be cleared (the second autocommand). + local client = vim.lsp.get_client_by_id(event.data.client_id) if client and client:supports_method('textDocument/documentHighlight', event.buf) then local highlight_augroup = vim.api.nvim_create_augroup('kickstart-lsp-highlight', { clear = false }) vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { @@ -882,25 +853,12 @@ require('lazy').setup({ { -- Highlight, edit, and navigate code 'nvim-treesitter/nvim-treesitter', - build = ':TSUpdate', config = function() + local filetypes = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'query', 'vim', 'vimdoc' } + require('nvim-treesitter').install(filetypes) vim.api.nvim_create_autocmd('FileType', { - pattern = { - 'bash', - 'c', - 'cs', - 'diff', - 'html', - 'lua', - 'markdown', - 'query', - 'vim', - 'help', - }, - callback = function(args) - local lang = vim.treesitter.language.get_lang(args.match) or args.match - pcall(vim.treesitter.start, args.buf, lang) - end, + pattern = filetypes, + callback = function() vim.treesitter.start() end, }) end, }, @@ -925,7 +883,7 @@ require('lazy').setup({ -- This is the easiest way to modularize your config. -- -- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going. - { import = 'custom.plugins' }, + -- { import = 'custom.plugins' }, -- -- For additional information with loading, sourcing and examples see `:help lazy.nvim-๐Ÿ”Œ-plugin-spec` -- Or use telescope! diff --git a/lua/custom/plugins/dotnet.lua b/lua/custom/plugins/dotnet.lua deleted file mode 100644 index 1b3d46f5..00000000 --- a/lua/custom/plugins/dotnet.lua +++ /dev/null @@ -1,486 +0,0 @@ --- ============================================================================= --- .NET / C# Development Setup --- ============================================================================= --- This file wires up everything needed for a productive .NET experience in --- Neovim: Roslyn LSP, GitHub Copilot (via blink.cmp), DAP debugging with --- netcoredbg, and Neotest for running xUnit/NUnit/MSTest tests. --- --- PREREQUISITES (install once on your system): --- - .NET SDK: https://dotnet.microsoft.com/download --- - Node.js > 20 (for Copilot): https://nodejs.org --- - On first launch run: :Copilot auth (one-time GitHub login) --- - Mason will auto-install: netcoredbg, csharpier --- - roslyn.nvim downloads its own language server on first use --- --- QUICK REFERENCE โ€” KEY BINDINGS --- (language-agnostic binds work everywhere; .NET-specific are noted) --- ============================================================================= --- --- โ”€โ”€ LSP NAVIGATION โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ --- grd Go to Definition (jump to where a symbol is defined) --- grD Go to Declaration (e.g. interface declaration) --- gri Go to Implementation (jump to concrete implementation) --- grr Find All References (list all usages in Telescope) --- grt Go to Type Definition (jump to the type of a variable) --- gO Document Symbols (fuzzy search symbols in this file) --- gW Workspace Symbols (fuzzy search symbols in whole project) --- K Hover Documentation (show docs / type info under cursor) --- grn Rename Symbol (rename across the whole project) --- gra Code Actions (fix suggestions, extract method, etc.) --- f Format Buffer (run csharpier on the current file) --- th Toggle Inlay Hints (show/hide parameter name hints) --- [d / ]d Previous / Next Diagnostic --- q Diagnostic Quickfix List --- sd Search Diagnostics (Telescope) --- --- โ”€โ”€ COMPLETION (blink.cmp) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ --- Open completion menu (or open docs if menu is open) --- / Next / Previous item (also / ) --- Accept completion (auto-imports if LSP supports it) --- Dismiss menu --- Toggle signature help (see function parameter hints) --- / Move through snippet expansions --- --- โ”€โ”€ GITHUB COPILOT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ --- Copilot suggestions appear in the blink.cmp completion menu automatically. --- They are ranked alongside LSP completions โ€” just navigate with /. --- :Copilot auth Re-authenticate with GitHub (run once on first setup) --- :Copilot status Check if Copilot is active --- --- โ”€โ”€ DEBUGGING (nvim-dap + netcoredbg) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ --- dc Continue / Start debug session --- db Toggle Breakpoint (set/unset on current line) --- dB Conditional Breakpoint (prompt for a condition expression) --- ds Step Over (F10 equivalent) --- di Step Into (F11 equivalent) --- do Step Out (Shift-F11 equivalent) --- dr Open REPL (interactive debug console) --- dl Re-run Last Session (repeat last debug config) --- du Toggle Debug UI (show/hide the dap-ui panels) --- de Evaluate Expression (hover eval under cursor) --- dE Evaluate (input prompt) (type an expression to evaluate) --- --- The debug UI opens automatically when a session starts and shows: --- Left panel: Scopes ยท Breakpoints ยท Call Stack ยท Watches --- Bottom panel: REPL ยท Console output --- --- โ”€โ”€ TESTING (neotest + neotest-dotnet) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ --- nn Run Nearest Test (test method under cursor) --- nf Run File Tests (all tests in current file) --- na Run All Tests (entire project/solution) --- ns Toggle Test Summary (tree view of all tests + status) --- no Show Test Output (output of last test run) --- np Show Short Output (condensed output panel) --- nd Debug Nearest Test (run test under cursor with DAP) --- nw Watch Nearest Test (re-run on file save) --- nx Stop Running Tests --- --- ============================================================================= - -return { - - -- =========================================================================== - -- 1. ROSLYN LSP (seblj/roslyn.nvim) - -- =========================================================================== - -- The same Roslyn language server that powers Visual Studio and Rider. - -- Downloads Microsoft.CodeAnalysis.LanguageServer automatically on first use. - -- Provides: IntelliSense, go-to-definition, find-references, rename, - -- code actions (extract method, add using, etc.), inlay hints, - -- and full project/solution awareness. - { - 'seblj/roslyn.nvim', - ft = { 'cs', 'vb' }, - dependencies = { - 'mason-org/mason.nvim', -- ensures mason is loaded first - }, - opts = { - -- roslyn.nvim finds and downloads the language server into stdpath('data'). - -- Set exe to override with a custom path if you manage the server yourself. - config = { - -- Pass extra capabilities from blink.cmp so the LSP knows we support - -- snippet completions, resolve, etc. - capabilities = vim.tbl_deep_extend( - 'force', - vim.lsp.protocol.make_client_capabilities(), - -- blink.cmp may not be loaded yet at spec parse time; we wrap in a - -- function via on_attach / capabilities below instead. - {} - ), - }, - -- In larger repos / monoliths this helps Roslyn search a bit wider for - -- the correct solution or project root. - broad_search = true, - -- Allow target switching when multiple solutions exist in the repo. - lock_target = false, - }, - config = function(_, opts) - -- Inject blink.cmp capabilities now that blink is guaranteed loaded. - local ok, blink = pcall(require, 'blink.cmp') - if ok then - opts.config = opts.config or {} - opts.config.capabilities = blink.get_lsp_capabilities(opts.config.capabilities) - end - - require('roslyn').setup(opts) - end, - }, - - -- =========================================================================== - -- 2. GITHUB COPILOT (zbirenbaum/copilot.lua + blink-cmp-copilot) - -- =========================================================================== - -- copilot.lua runs the Copilot LSP in the background. - -- We disable the built-in ghost-text / panel UI and instead surface - -- completions through blink.cmp so everything comes from one menu. - { - 'zbirenbaum/copilot.lua', - event = 'InsertEnter', - opts = { - -- Disable copilot.lua's own UI โ€” blink.cmp owns the completion menu. - suggestion = { enabled = false }, - panel = { enabled = false }, - -- Explicitly enable C# (and a few other useful filetypes). - filetypes = { - cs = true, - lua = true, - python = true, - javascript = true, - typescript = true, - -- Disable noisy filetypes. - markdown = false, - help = false, - gitcommit = false, - }, - -- Node.js must be > 20. - copilot_node_command = 'node', - }, - }, - - -- blink-cmp-copilot bridges copilot.lua into blink.cmp as a source provider. - -- Copilot completions appear in the menu with a icon and "Copilot" label. - { - 'giuxtaposition/blink-cmp-copilot', - dependencies = { 'zbirenbaum/copilot.lua' }, - -- blink.cmp is already configured in init.lua; we patch its sources table - -- here so we don't have to touch the existing config. - specs = { - { - 'saghen/blink.cmp', - optional = true, - opts = { - sources = { - default = { 'lsp', 'path', 'snippets', 'copilot' }, - providers = { - copilot = { - name = 'copilot', - module = 'blink-cmp-copilot', - -- Show Copilot items after LSP items in the menu. - score_offset = -1, - async = true, - -- Give it a recognisable icon in the completion menu. - transform_items = function(_, items) - for _, item in ipairs(items) do - item.kind_icon = '' - item.kind_name = 'Copilot' - end - return items - end, - }, - }, - }, - }, - }, - }, - }, - - -- =========================================================================== - -- 3. DEBUGGING (nvim-dap + nvim-dap-ui + mason-nvim-dap) - -- =========================================================================== - -- netcoredbg is the open-source .NET debugger that understands the DAP - -- protocol. mason-nvim-dap installs it automatically. - { - 'mfussenegger/nvim-dap', - dependencies = { - -- Automatic installer / bridge between mason and dap adapters. - { - 'jay-babu/mason-nvim-dap.nvim', - dependencies = { 'mason-org/mason.nvim' }, - opts = { - -- Let mason-nvim-dap install and configure netcoredbg. - ensure_installed = { 'netcoredbg' }, - automatic_installation = true, - handlers = {}, -- use default handlers for installed adapters - }, - }, - - -- A full debug UI: scopes, locals, call stack, breakpoints, REPL. - { - 'rcarriga/nvim-dap-ui', - dependencies = { 'nvim-neotest/nvim-nio' }, - config = function() - local dap = require 'dap' - local dapui = require 'dapui' - - dapui.setup { - -- Layout: left sidebar + bottom panel โ€” mirrors a typical IDE layout. - layouts = { - { - -- Left sidebar: variables, call stack, breakpoints, watches. - position = 'left', - size = 40, - elements = { - { id = 'scopes', size = 0.35 }, - { id = 'stacks', size = 0.35 }, - { id = 'breakpoints', size = 0.15 }, - { id = 'watches', size = 0.15 }, - }, - }, - { - -- Bottom tray: REPL for live evaluation + program console output. - position = 'bottom', - size = 12, - elements = { - { id = 'repl', size = 0.5 }, - { id = 'console', size = 0.5 }, - }, - }, - }, - } - - -- Auto-open the UI when a debug session starts. - dap.listeners.after.event_initialized['dapui_config'] = function() - dapui.open() - end - -- Auto-close the UI when the session ends or terminates. - dap.listeners.before.event_terminated['dapui_config'] = function() - dapui.close() - end - dap.listeners.before.event_exited['dapui_config'] = function() - dapui.close() - end - end, - }, - - -- Virtual text shows variable values inline while stepping through code. - { - 'theHamsta/nvim-dap-virtual-text', - opts = { - -- Show the value of the variable at the current scope inline. - display_callback = function(variable, _, _, _, options) - if #variable.value > 60 then - return ' ' .. string.sub(variable.value, 1, 57) .. '...' - end - return ' ' .. variable.value - end, - }, - }, - }, - - config = function() - local dap = require 'dap' - - -- โ”€โ”€ Adapter โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ - -- mason-nvim-dap installs netcoredbg into mason's bin directory. - -- We resolve the path at runtime so it works on any machine. - local mason_bin = vim.fn.stdpath 'data' .. '/mason/bin' - local netcoredbg_cmd = mason_bin .. '/netcoredbg' - -- On Windows mason wraps executables in .cmd files. - if vim.fn.has 'win32' == 1 then - netcoredbg_cmd = mason_bin .. '/netcoredbg.cmd' - end - - dap.adapters.coreclr = { - type = 'executable', - command = netcoredbg_cmd, - args = { '--interpreter=vscode' }, - } - - -- โ”€โ”€ Helper: prompt for / remember DLL path โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ - -- On first launch you'll be asked for the path to the compiled DLL. - -- The answer is cached for the rest of the session; you're only re-asked - -- if you confirm you want to change it. - local function get_dll_path() - if vim.g.dotnet_last_dll_path == nil then - vim.g.dotnet_last_dll_path = vim.fn.input( - 'Path to DLL: ', - vim.fn.getcwd() .. '/bin/Debug/', - 'file' - ) - else - local change = vim.fn.confirm( - 'Reuse last DLL?\n' .. vim.g.dotnet_last_dll_path, - '&Yes\n&No', - 1 - ) - if change == 2 then - vim.g.dotnet_last_dll_path = vim.fn.input( - 'Path to DLL: ', - vim.g.dotnet_last_dll_path, - 'file' - ) - end - end - return vim.g.dotnet_last_dll_path - end - - -- โ”€โ”€ Helper: optional pre-build โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ - local function maybe_build() - local build = vim.fn.confirm('Build project first?', '&Yes\n&No', 2) - if build == 1 then - local proj = vim.fn.input( - 'Path to .csproj/.sln: ', - vim.g.dotnet_last_proj_path or (vim.fn.getcwd() .. '/'), - 'file' - ) - vim.g.dotnet_last_proj_path = proj - vim.notify('Building ' .. proj .. ' โ€ฆ', vim.log.levels.INFO) - local result = os.execute('dotnet build -c Debug "' .. proj .. '" > /dev/null 2>&1') - if result == 0 then - vim.notify('Build succeeded', vim.log.levels.INFO) - else - vim.notify('Build FAILED โ€” check :messages', vim.log.levels.ERROR) - end - end - end - - -- โ”€โ”€ Launch configurations โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ - -- Shared across cs and fsharp. - local dotnet_launch = { - { - type = 'coreclr', - name = 'Launch .NET (netcoredbg)', - request = 'launch', - program = function() - maybe_build() - return get_dll_path() - end, - }, - { - -- Attach to a running process (e.g. an already-running web server). - type = 'coreclr', - name = 'Attach to process', - request = 'attach', - processId = require('dap.utils').pick_process, - }, - } - - dap.configurations.cs = dotnet_launch - dap.configurations.fsharp = dotnet_launch - - -- โ”€โ”€ Keybinds โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ - -- See the header comment at the top of this file for full descriptions. - local map = function(keys, func, desc) - vim.keymap.set('n', keys, func, { desc = 'Debug: ' .. desc }) - end - - map('dc', dap.continue, '[C]ontinue / Start') - map('db', dap.toggle_breakpoint, 'Toggle [B]reakpoint') - map('dB', function() - dap.set_breakpoint(vim.fn.input 'Breakpoint condition: ') - end, 'Conditional [B]reakpoint') - map('ds', dap.step_over, '[S]tep Over') - map('di', dap.step_into, 'Step [I]nto') - map('do', dap.step_out, 'Step [O]ut') - map('dr', dap.repl.open, 'Open [R]EPL') - map('dl', dap.run_last, 'Run [L]ast') - map('du', function() require('dapui').toggle() end, 'Toggle [U]I') - map('de', function() require('dapui').eval() end, '[E]val under cursor') - map('dE', function() - require('dapui').eval(vim.fn.input 'Expression: ') - end, '[E]val expression') - - -- Register the d group name with which-key (if loaded). - local ok, wk = pcall(require, 'which-key') - if ok then - wk.add { { 'd', group = '[D]ebug' } } - end - end, - }, - - -- =========================================================================== - -- 4. TESTING (nvim-neotest + neotest-dotnet) - -- =========================================================================== - -- neotest-dotnet discovers xUnit, NUnit, and MSTest tests automatically by - -- scanning for [Fact], [Theory], [Test], [TestCase], etc. attributes. - { - 'nvim-neotest/neotest', - dependencies = { - 'nvim-lua/plenary.nvim', - 'antoinemadec/FixCursorHold.nvim', -- required by neotest - 'nvim-treesitter/nvim-treesitter', - -- .NET adapter โ€” supports xUnit, NUnit, MSTest. - 'Issafalcon/neotest-dotnet', - }, - config = function() - require('neotest').setup { - adapters = { - require('neotest-dotnet') { - -- dap integration: nd will attach the debugger to the test. - dap = { justMyCode = false }, - -- Discover tests using the dotnet CLI runner. - -- Set to 'omnisharp' if you prefer the OmniSharp test runner. - dotnet_additional_args = {}, - }, - }, - -- Show pass/fail icons in the gutter next to each test. - status = { enabled = true, signs = true, virtual_text = false }, - -- Open the output panel automatically for short failures. - output = { enabled = true, open_on_run = 'short' }, - -- Use a bottom split for the output panel. - output_panel = { - enabled = true, - open = 'botright split | resize 15', - }, - } - - -- โ”€โ”€ Keybinds โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ - -- See the header comment at the top of this file for full descriptions. - local nt = require 'neotest' - local map = function(keys, func, desc) - vim.keymap.set('n', keys, func, { desc = 'Test: ' .. desc }) - end - - map('nn', function() nt.run.run() end, 'Run [N]earest test') - map('nf', function() nt.run.run(vim.fn.expand '%') end, 'Run [F]ile tests') - map('na', function() nt.run.run(vim.fn.getcwd()) end, 'Run [A]ll tests') - map('ns', function() nt.summary.toggle() end, 'Toggle [S]ummary panel') - map('no', function() nt.output.open { enter = true } end, 'Show [O]utput') - map('np', function() nt.output_panel.toggle() end, 'Toggle output [P]anel') - map('nd', function() nt.run.run { strategy = 'dap' } end, '[D]ebug nearest test') - map('nw', function() nt.watch.toggle(vim.fn.expand '%') end, '[W]atch file tests') - map('nx', function() nt.run.stop() end, 'Stop running tests') - - -- Register the n group name with which-key (if loaded). - local ok, wk = pcall(require, 'which-key') - if ok then - wk.add { { 'n', group = '[N]eotest' } } - end - end, - }, - - -- =========================================================================== - -- 5. CSHARPIER (formatter, installed via Mason) - -- =========================================================================== - -- csharpier is the opinionated C# formatter (like gofmt/prettier for C#). - -- It is installed by mason-tool-installer below and wired into conform.nvim. - { - -- Re-use mason-tool-installer (already set up in init.lua) to ensure - -- csharpier is installed. We declare it as a separate spec here so this - -- file is self-contained; lazy.nvim merges duplicate plugin specs. - 'WhoIsSethDaniel/mason-tool-installer.nvim', - optional = true, - opts = function(_, opts) - opts.ensure_installed = opts.ensure_installed or {} - vim.list_extend(opts.ensure_installed, { 'csharpier', 'roslyn' }) - end, - }, - { - -- Patch conform.nvim to format C# files with csharpier. - -- This merges cleanly with the existing conform setup in init.lua. - 'stevearc/conform.nvim', - optional = true, - opts = function(_, opts) - opts.formatters_by_ft = opts.formatters_by_ft or {} - opts.formatters_by_ft.cs = { 'csharpier' } - end, - }, -}