From 426064413cb537e29b727e1853df87a97e9d64f6 Mon Sep 17 00:00:00 2001 From: Jannik Donker Date: Wed, 8 Jul 2026 14:48:25 +0200 Subject: [PATCH] improved debugging config --- init.lua | 1 + lua/debugging.lua | 90 +++++++++++++++++++++++++++++++++++++++++++++++ lua/keymaps.lua | 6 ---- lua/lsp.lua | 5 +++ lua/plugins.lua | 8 ++--- 5 files changed, 98 insertions(+), 12 deletions(-) create mode 100644 lua/debugging.lua diff --git a/init.lua b/init.lua index 7166cf7..8d86430 100644 --- a/init.lua +++ b/init.lua @@ -2,3 +2,4 @@ require("options") require("plugins") require("lsp") require("keymaps") +require("debugging") diff --git a/lua/debugging.lua b/lua/debugging.lua new file mode 100644 index 0000000..ef5c5c6 --- /dev/null +++ b/lua/debugging.lua @@ -0,0 +1,90 @@ +local dap, dapui = require("dap"), require("dapui") + +-- Install debug adapters via Mason (same pattern as the LSP tool loop in +-- plugins.lua). codelldb -> c/cpp/rust, debugpy -> python, +-- js-debug-adapter -> node/ts. java-debug-adapter is installed by the LSP +-- ensure loop and wired through jdtls (see lua/lsp.lua). +local registry = require("mason-registry") +registry.refresh(function() + for _, tool in ipairs({ "debugpy", "codelldb", "js-debug-adapter" }) do + local ok, pkg = pcall(registry.get_package, tool) + if ok and not pkg:is_installed() then pkg:install() end + end +end) + +dapui.setup() +require("nvim-dap-virtual-text").setup() + +-- Auto-wire adapters + default launch configs for every mason-installed +-- adapter. Empty handlers = use mason-nvim-dap's default handler for all. +-- To add a language later: install its adapter in the loop above; it is +-- configured here automatically. Override by defining dap.configurations. +-- below this call. +require("mason-nvim-dap").setup({ + ensure_installed = {}, + automatic_installation = false, + handlers = {}, +}) + +-- JS/TS (node): mason-nvim-dap ships no default handler for js-debug-adapter, +-- so wire the pwa-node adapter and launch/attach configs manually. +dap.adapters["pwa-node"] = { + type = "server", + host = "localhost", + port = "${port}", + executable = { + command = "node", + args = { + vim.fs.joinpath(vim.fn.stdpath("data"), "mason", "packages", + "js-debug-adapter", "js-debug", "src", "dapDebugServer.js"), + "${port}", + }, + }, +} +for _, ft in ipairs({ "javascript", "typescript" }) do + dap.configurations[ft] = { + { + type = "pwa-node", + request = "launch", + name = "Launch file", + program = "${file}", + cwd = "${workspaceFolder}", + }, + { + type = "pwa-node", + request = "attach", + name = "Attach to process", + processId = require("dap.utils").pick_process, + cwd = "${workspaceFolder}", + }, + } +end + +-- Open/close the dap-ui panels automatically with the session. +dap.listeners.before.attach.dapui_config = function() dapui.open() end +dap.listeners.before.launch.dapui_config = function() dapui.open() end +dap.listeners.before.event_terminated.dapui_config = function() dapui.close() end +dap.listeners.before.event_exited.dapui_config = function() dapui.close() end + +-- VS Code standard F-keys +local map = vim.keymap.set +map("n", "", dap.continue, { desc = "Debug: continue / start" }) +map("n", "", dap.terminate, { desc = "Debug: stop" }) +map("n", "", dap.restart, { desc = "Debug: restart" }) +map("n", "", dap.pause, { desc = "Debug: pause" }) +map("n", "", dap.toggle_breakpoint, { desc = "Debug: toggle breakpoint" }) +map("n", "", dap.step_over, { desc = "Debug: step over" }) +map("n", "", dap.step_into, { desc = "Debug: step into" }) +map("n", "", dap.step_out, { desc = "Debug: step out" }) + +-- Leader maps (preserve the previous d* bindings + a few niceties; +-- discoverable via Pick keymaps thanks to desc). +map("n", "duo", dapui.open, { desc = "Debug: open UI" }) +map("n", "duc", dapui.close, { desc = "Debug: close UI" }) +map("n", "dbp", dap.toggle_breakpoint, { desc = "Debug: toggle breakpoint" }) +map("n", "drc", dap.run_to_cursor, { desc = "Debug: run to cursor" }) +map("n", "dr", dap.repl.toggle, { desc = "Debug: toggle REPL" }) +map("n", "de", function() dapui.eval() end, { desc = "Debug: eval under cursor" }) +map("n", "dB", function() + dap.set_breakpoint(vim.fn.input("Breakpoint condition: ")) +end, { desc = "Debug: conditional breakpoint" }) diff --git a/lua/keymaps.lua b/lua/keymaps.lua index 2f698c5..6dc84c0 100644 --- a/lua/keymaps.lua +++ b/lua/keymaps.lua @@ -40,12 +40,6 @@ map("n", "", "Pick help", { desc = "Find: help tags" }) map("n", "", "Oil", { desc = "File explorer (Oil)" }) map("n", "", "Pick keymaps", { desc = "Find: keymaps" }) --- DAP -map("n", "duo", function() require("dapui").open() end, { desc = "Debug: open UI" }) -map("n", "duc", function() require("dapui").close() end, { desc = "Debug: close UI" }) -map("n", "dbp", function() require("dap").toggle_breakpoint() end, { desc = "Debug: toggle breakpoint" }) -map("n", "drc", function() require("dap").run_to_cursor() end, { desc = "Debug: run to cursor" }) - -- Spell map("n", "sc", function() vim.wo.spell = not vim.wo.spell diff --git a/lua/lsp.lua b/lua/lsp.lua index cc4780c..679ef96 100644 --- a/lua/lsp.lua +++ b/lua/lsp.lua @@ -71,5 +71,10 @@ vim.api.nvim_create_autocmd("FileType", { }, }, }) + + -- Register Java debug configs (the rest of DAP lives in + -- lua/debugging.lua; Java must set up here, inside the jdtls attach). + require("jdtls").setup_dap({ hotcodereplace = "auto" }) + require("jdtls.dap").setup_dap_main_class_configs() end, }) diff --git a/lua/plugins.lua b/lua/plugins.lua index 7ed4cf8..fd8e739 100644 --- a/lua/plugins.lua +++ b/lua/plugins.lua @@ -27,6 +27,8 @@ vim.pack.add({ { src = "https://github.com/folke/trouble.nvim" }, { src = "https://github.com/nvim-neotest/nvim-nio" }, { src = "https://github.com/rcarriga/nvim-dap-ui" }, + { src = "https://github.com/theHamsta/nvim-dap-virtual-text" }, + { src = "https://github.com/jay-babu/mason-nvim-dap.nvim" }, { src = "https://github.com/michaelrommel/nvim-silicon" }, { src = "https://github.com/hat0uma/csvview.nvim.git" }, { src = "https://github.com/Thiago4532/mdmath.nvim" }, @@ -270,9 +272,3 @@ registry.refresh(function() if ok and not pkg:is_installed() then pkg:install() end end end) - --- DAP UI wiring -local dap, dapui = require("dap"), require("dapui") -dapui.setup() -dap.listeners.before.attach.dapui_config = function() dapui.open() end -dap.listeners.before.launch.dapui_config = function() dapui.open() end