vim.pack.add({ { src = "https://github.com/mfussenegger/nvim-dap" }, { src = "https://github.com/rcarriga/nvim-dap-ui" }, { src = "https://github.com/nvim-neotest/nvim-nio" }, }) local dap = require("dap") local dapui = require("dapui") local lldb_dap = vim.fn.exepath("lldb-dap") if lldb_dap == "" then vim.notify("lldb-dap not found — install lldb (pacman -S lldb)", vim.log.levels.WARN) end dap.adapters.lldb = { type = "executable", command = lldb_dap, name = "lldb", options = { initialize_timeout_sec = 20 }, } local function project_binary() local cwd = vim.fn.getcwd() return cwd .. "/" .. vim.fn.fnamemodify(cwd, ":t") end dap.configurations.odin = { { type = "lldb", request = "launch", name = "Launch Odin", cwd = function() return vim.fn.getcwd() end, program = project_binary, }, } dapui.setup({}) dap.listeners.after.event_initialized["dapui"] = dapui.open local neotree_width = 30 local function close_dapui() dapui.close() for _, win in ipairs(vim.api.nvim_list_wins()) do if vim.bo[vim.api.nvim_win_get_buf(win)].filetype == "neo-tree" then vim.api.nvim_win_set_width(win, neotree_width) end end end dap.listeners.before.event_terminated["dapui_restore"] = close_dapui dap.listeners.before.event_exited["dapui_restore"] = close_dapui local function run_or_continue() if dap.session() then dap.continue() elseif vim.bo.filetype == "odin" then vim.notify("odin: building...", vim.log.levels.INFO) vim.system({ "odin", "build", ".", "-debug" }, { cwd = vim.fn.getcwd() }, function(obj) vim.schedule(function() if obj.code ~= 0 then vim.notify("odin build failed (code " .. obj.code .. ")", vim.log.levels.ERROR) return end vim.api.nvim_echo({}, false, {}) dap.run(dap.configurations.odin[1]) end) end) else dap.continue() end end local maps = { { "n", "", run_or_continue, "Start/Continue" }, { "n", "dc", run_or_continue, "Start/Continue" }, { "n", "", function() dap.step_over() end, "Step Over" }, { "n", "do", function() dap.step_over() end, "Step Over" }, { "n", "", function() dap.step_into() end, "Step Into" }, { "n", "di", function() dap.step_into() end, "Step Into" }, { "n", "", function() dap.step_out() end, "Step Out" }, { "n", "dO", function() dap.step_out() end, "Step Out" }, { "n", "db", function() dap.toggle_breakpoint() end, "Toggle Breakpoint" }, { "n", "dB", function() dap.set_breakpoint(vim.fn.input("Condition: ")) end, "Conditional Breakpoint" }, { "n", "dt", function() dap.terminate() end, "Terminate" }, { "n", "dq", function() dap.close() end, "Close Session" }, { "n", "dr", function() dap.repl.toggle() end, "REPL" }, { "n", "du", function() dapui.toggle() end, "Toggle DAP UI" }, { "n", "d?", function() dap.list_breakpoints() end, "List Breakpoints" }, } for _, map in ipairs(maps) do vim.keymap.set(map[1], map[2], map[3], { desc = "DAP: " .. map[4] }) end