return {
    "mfussenegger/nvim-dap",
    dependencies = {
        { "nvim-neotest/nvim-nio" },
        { "rcarriga/nvim-dap-ui" },
        { "theHamsta/nvim-dap-virtual-text" },
        { "nvim-telescope/telescope-dap.nvim" },
    },
    -- stylua: ignore
    keys = {
        { "<leader>bR", function() require("dap").run_to_cursor() end,                               desc = "Run to Cursor", },
        { "<leader>bE", function() require("dapui").eval(vim.fn.input "[Expression] > ") end,        desc = "Evaluate Input", },
        { "<leader>bC", function() require("dap").set_breakpoint(vim.fn.input "[Condition] > ") end, desc = "Conditional Breakpoint", },
        { "<leader>bU", function() require("dapui").toggle() end,                                    desc = "Toggle UI", },
        { "<leader>bb", function() require("dap").step_back() end,                                   desc = "Step Back", },
        { "<leader>bc", function() require("dap").continue() end,                                    desc = "Continue", },
        { "<leader>bd", function() require("dap").disconnect() end,                                  desc = "Disconnect", },
        { "<leader>be", function() require("dapui").eval() end,                                      desc = "Evaluate", },
        { "<leader>bg", function() require("dap").session() end,                                     desc = "Get Session", },
        { "<leader>bh", function() require("dap.ui.widgets").hover() end,                            desc = "Hover Variables", },
        { "<leader>bS", function() require("dap.ui.widgets").scopes() end,                           desc = "Scopes", },
        { "<leader>bi", function() require("dap").step_into() end,                                   desc = "Step Into", },
        { "<leader>bo", function() require("dap").step_over() end,                                   desc = "Step Over", },
        { "<leader>bp", function() require("dap").pause.toggle() end,                                desc = "Pause", },
        { "<leader>bq", function() require("dap").close() end,                                       desc = "Quit", },
        { "<leader>br", function() require("dap").repl.toggle() end,                                 desc = "Toggle REPL", },
        { "<leader>bs", function() require("dap").continue() end,                                    desc = "Start", },
        { "<leader>bt", function() require("dap").toggle_breakpoint() end,                           desc = "Toggle Breakpoint", },
        { "<leader>bx", function() require("dap").terminate() end,                                   desc = "Terminate", },
        { "<leader>bu", function() require("dap").step_out() end,                                    desc = "Step Out", },
    },
    config = function()
        require("nvim-dap-virtual-text").setup({
            commented = true,
        })

        local dap, dapui = require("dap"), require("dapui")
        dapui.setup({})

        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

        vim.fn.sign_define("DapBreakpoint", { text = "●", texthl = "DapBreakpoint", linehl = "", numhl = ""})
        vim.fn.sign_define("DapBreakpointCondition", { text = "●", texthl = "DapBreakpointCondition", linehl = "", numhl = ""})
        vim.fn.sign_define("DapLogPoint", { text = "◆", texthl = "DapLogPoint", linehl = "", numhl = ""})
        vim.fn.sign_define('DapStopped', { text='', texthl='DapStopped', linehl='DapStopped', numhl= 'DapStopped' })

        dap.configurations.python = {
            {
                type = "python",
                request = "launch",
                name = "Launch file",

                -- Options below are for debugpy, see https://github.com/microsoft/debugpy/wiki/Debug-configuration-settings for supported options

                program = "${file}", -- This configuration will launch the current file if used.
                pythonPath = function()
                    local cwd = vim.fn.getcwd()
                    if vim.fn.executable(cwd .. "/venv/bin/python") == 1 then
                        return cwd .. "/venv/bin/python"
                    elseif vim.fn.executable(cwd .. "/.venv/bin/python") == 1 then
                        return cwd .. "/.venv/bin/python"
                    else
                        return "/usr/bin/python"
                    end
                end,
            },
        }

        dap.adapters.python = function(cb, config)
            if config.request == "attach" then
                ---@diagnostic disable-next-line: undefined-field
                local port = (config.connect or config).port
                ---@diagnostic disable-next-line: undefined-field
                local host = (config.connect or config).host or "127.0.0.1"
                cb({
                    type = "server",
                    port = assert(port, "`connect.port` is required for a python `attach` configuration"),
                    host = host,
                    options = {
                        source_filetype = "python",
                    },
                })
            else
                cb({
                    type = "executable",
                    command = vim.fn.stdpath("data") .. '/mason/packages/debugpy/venv/bin/python',
                    args = { "-m", "debugpy.adapter" },
                    options = {
                        source_filetype = "python",
                    },
                })
            end
        end
    end,
}