local function fzf_pick_executable() return coroutine.create(function(coro) local current_cwd = vim.fn.getcwd():gsub("\\", "/") require("fzf-lua").files({ cwd = current_cwd, cmd = "fd --type x --hidden --no-ignore", previewer = false, header = false, prompt = "Select Executable ❯ ", winopts = { title = " Select Executable ", title_pos = "center", height = 0.40, width = 0.60, }, actions = { ["default"] = function(selected) if selected and selected[1] then -- 1. Strip icons and formatting spaces to isolate the file string local entry = require("fzf-lua.path").entry_to_file(selected[1], { cwd = current_cwd }) -- 2. Automatically resolve it to an absolute path (handles relative or absolute safely) local full_path = vim.fn.fnamemodify(entry.path, ":p") -- 3. Clean up slashes and hand it to DAP coroutine.resume(coro, full_path:gsub("\\", "/")) else coroutine.resume(coro, vim.fn.empty()) end end } }) end) end local function start_debug_session() local is_windows = vim.fn.has("win32") == 1 local dap = require("dap") -- 3. Platform-agnostic Launcher Configuration if not is_windows then dap.configurations.cpp = { { name = "Launch file", type = "codelldb", request = "launch", program = fzf_pick_executable, cwd = '${workspaceFolder}', stopOnEntry = false, args = {}, }, } else local vscode = require('dap.ext.vscode') local launch_json = vim.fn.getcwd() .. "/.vscode/launch.json" if vim.fn.filereadable(launch_json) == 1 then dap.configurations.cpp = {} dap.configurations.c = {} -- 1. CRUCIAL FIX: Alias the adapters directly so nvim-dap doesn't complain about a missing engine --if dap.adapters.cppdbg then -- dap.adapters.cppvsdbg = dap.adapters.cppdbg --elseif dap.adapters.codelldb then -- dap.adapters.cppvsdbg = dap.adapters.codelldb --end -- 2. Map types inside launch.json to your C++ filetypes vscode.type_to_filetypes = { cppvsdbg = { "cpp", "c" }, cppdbg = { "cpp", "c" }, codelldb = { "cpp", "c" }, } else -- No launch.json exists. Re-inject your FZF picker template rules dap.configurations.cpp = { { name = "Launch file", type = "cppdbg", request = "launch", program = fzf_pick_executable, cwd = "${workspaceFolder}", stopOnEntry = false, -- Crucial configurations for Microsoft cpptools: -- On Windows, this automatically uses MinGW/MSVC underlying debugger engines MIMode = is_windows and "gdb" or "lldb", miDebuggerPath = is_windows and "gdb.exe" or nil, -- Uses system path for gdb on Windows setupCommands = { { text = "-enable-pretty-printing", description = "enable pretty printing", ignoreFailures = false, }, }, }, } end end dap.continue() end vim.keymap.set("n", "cdc", start_debug_session, { desc = "Debug: Start/Continue with Smart Config" }) return { "mfussenegger/nvim-dap", dependencies = { "rcarriga/nvim-dap-ui", "theHamsta/nvim-dap-virtual-text", "nvim-neotest/nvim-nio", "williamboman/mason.nvim", "jay-babu/mason-nvim-dap.nvim", }, config = function() local dap = require("dap") local dapui = require("dapui") -- Initialize UI and virtual text components dapui.setup() require("nvim-dap-virtual-text").setup() -- Automatically manage debugger installations via Mason require("mason-nvim-dap").setup({ ensure_installed = { "codelldb", "cppdbg" }, -- Auto-installs CodeLLDB automatic_installation = true, }) -- Automatically open/close DAP UI panels dap.listeners.after.event_initialized["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 -- Step 2 & 3 configurations will go here... -- 1. Detect operating system local is_windows = vim.fn.has("win32") == 1 local ext = is_windows and ".exe" or "" -- 2. Platform-agnostic CodeLLDB Adapter setup local mason_registry = require("mason-registry") local codelldb = mason_registry.get_package("codelldb") local extension_path = codelldb:get_install_path() .. "/extension/" -- CodeLLDB executable is in different subfolders depending on Mason's package version local codelldb_path = extension_path .. "adapter/codelldb" .. ext local cpptools_pkg = mason_registry.get_package("cpptools") local cpptools_path = cpptools_pkg:get_install_path() .. "/extension/debugAdapters/bin/OpenDebugAD7" .. ext dap.adapters.codelldb = { type = 'server', port = "${port}", executable = { command = codelldb_path, args = {"--port", "${port}"}, detached = false, } } dap.adapters.cppdbg = { id = "cppdbg", type = "executable", command = cpptools_path, -- For Windows subprocess tracking stability options = { detached = not is_windows, }, } dap.adapters.cppvsdbg = { type = 'server', port = "${port}", executable = { command = codelldb_path, args = {"--port", "${port}"}, detached = false, } } -- 3. Platform-agnostic Launcher Configuration if not is_windows then dap.configurations.cpp = { { name = "Launch file", type = "codelldb", request = "launch", program = fzf_pick_executable, cwd = '${workspaceFolder}', stopOnEntry = false, args = {}, }, } else dap.configurations.cpp = { { name = "Launch file", type = "cppdbg", request = "launch", program = fzf_pick_executable, cwd = "${workspaceFolder}", stopOnEntry = false, -- Crucial configurations for Microsoft cpptools: -- On Windows, this automatically uses MinGW/MSVC underlying debugger engines MIMode = is_windows and "gdb" or "lldb", miDebuggerPath = is_windows and "gdb.exe" or nil, -- Uses system path for gdb on Windows setupCommands = { { text = "-enable-pretty-printing", description = "enable pretty printing", ignoreFailures = false, }, }, }, } end dap.configurations.c = dap.configurations.cpp end }