-- Python launch configs (nvim-dap-python), wired to the debugpy adapter -- that mason-nvim-dap.nvim installs (dap.lua). Kept in its own file since -- this is the "per-language" half of debugging, parallel to how -- ftplugin/python.lua holds Python-only settings. return { "mfussenegger/nvim-dap-python", -- Not left to lazy-load off `ft = "python"`: dap.lua's dc picker -- works from any window (not just a Python buffer) and needs -- dap.adapters.python already registered by the time a config is picked, -- even if no .py buffer has been opened yet this session. lazy = false, -- mason.nvim is listed directly (not just transitively via dap.lua) -- because config() below needs require("mason-registry") to be loadable -- from startup, same reasoning as lazy = false above. dependencies = { "mfussenegger/nvim-dap", "mason-org/mason.nvim" }, config = function() local registry = require("mason-registry") local pkg = registry.get_package("debugpy") -- debugpy_path is the interpreter that runs the debug *adapter* itself -- (Mason's isolated venv) - it does not control which Python runs your -- script. dap-python defaults that to the active venv/system python3; -- project-specific venvs may need a manual `pythonPath` override in a -- generated launch config later. local debugpy_path = pkg:get_install_path() .. "/venv/bin/python" local function setup() require("dap-python").setup(debugpy_path) -- nvim-dap-python doesn't expose adapter.options for tuning, and -- nvim-dap's default terminate-request timeout (3s) is tight enough -- that debugpy's real response can arrive just after nvim-dap already -- gave up and moved on ("No callback found" in dap.log) - dt -- still works, but dap.session() doesn't clear for a few extra -- seconds, so dc right after can catch it still "active". -- Wrap the adapter dap-python just registered to give it more room. local dap = require("dap") local base_adapter = dap.adapters.python dap.adapters.python = function(cb, config) base_adapter(function(adapter) adapter.options = adapter.options or {} adapter.options.disconnect_timeout_sec = 8 cb(adapter) end, config) end end if pkg:is_installed() then setup() else -- dap.lua's mason-nvim-dap ensure_installed triggers debugpy's -- install, but that's async - on a fresh machine (or before it -- finishes) debugpy_path doesn't exist on disk yet, and dc -- would fail with a raw ENOENT from debugpy itself instead of a clear -- message. Wire up the adapter once the install actually completes -- instead of pointing it at a path that isn't there yet. vim.notify( "debugpy not installed yet - dap.lua's ensure_installed should be" .. " installing it now (check :Mason); run :MasonInstall debugpy" .. " if it doesn't show up there. Debugging will work once it's" .. " done.", vim.log.levels.WARN ) registry:on("package:install:success", function(installed_pkg) if installed_pkg.name == "debugpy" then setup() end end) end end, }