feat(dap): enhance breakpoint editing

The key-mapping `<leader>dB` (in `lazyvim.plugins.extras.dap.core`) is now configured to guide users through the process of adding a `condition`, `hitCondition`, and `logMessage` to a breakpoint.

This also allows attributes that have already been set to be edited, instead of having to start from scratch each time you want to update one of these fields.

These breakpoints will persist for the duration of the session.

Tested with Neovim v0.11.1, and LazyVim/starter (803bc18)
This commit is contained in:
Brian Lehrer 2025-05-13 14:25:10 -07:00
parent 25abbf546d
commit 537c45fe45

View file

@ -31,26 +31,90 @@ return {
}, },
}, },
-- stylua: ignore keys = function(_, keys)
keys = { local dap = require("dap")
{ "<leader>dB", function() require("dap").set_breakpoint(vim.fn.input('Breakpoint condition: ')) end, desc = "Breakpoint Condition" },
{ "<leader>db", function() require("dap").toggle_breakpoint() end, desc = "Toggle Breakpoint" }, local function edit_breakpoint()
{ "<leader>dc", function() require("dap").continue() end, desc = "Run/Continue" }, -- Search for an existing breakpoint on this line in this buffer
{ "<leader>da", function() require("dap").continue({ before = get_args }) end, desc = "Run with Args" }, ---@return dap.SourceBreakpoint bp that was either found, or an empty placeholder
{ "<leader>dC", function() require("dap").run_to_cursor() end, desc = "Run to Cursor" }, local function find_bp()
{ "<leader>dg", function() require("dap").goto_() end, desc = "Go to Line (No Execute)" }, local buf_bps = require("dap.breakpoints").get(vim.fn.bufnr())[vim.fn.bufnr()]
{ "<leader>di", function() require("dap").step_into() end, desc = "Step Into" }, ---@type dap.SourceBreakpoint
{ "<leader>dj", function() require("dap").down() end, desc = "Down" }, local bp = { condition = "", logMessage = "", hitCondition = "", line = vim.fn.line(".") }
{ "<leader>dk", function() require("dap").up() end, desc = "Up" }, for _, candidate in ipairs(buf_bps) do
{ "<leader>dl", function() require("dap").run_last() end, desc = "Run Last" }, if candidate.line and candidate.line == vim.fn.line(".") then
{ "<leader>do", function() require("dap").step_out() end, desc = "Step Out" }, bp = candidate
{ "<leader>dO", function() require("dap").step_over() end, desc = "Step Over" }, break
{ "<leader>dP", function() require("dap").pause() end, desc = "Pause" }, end
{ "<leader>dr", function() require("dap").repl.toggle() end, desc = "Toggle REPL" }, end
{ "<leader>ds", function() require("dap").session() end, desc = "Session" }, return bp
{ "<leader>dt", function() require("dap").terminate() end, desc = "Terminate" }, end
{ "<leader>dw", function() require("dap.ui.widgets").hover() end, desc = "Widgets" },
}, -- Elicit customization via a UI prompt
---@param bp dap.SourceBreakpoint a breakpoint
local function customize_bp(bp)
local props = {
["Condition"] = {
value = bp.condition,
setter = function(v)
bp.condition = v
end,
},
["Hit Condition"] = {
value = bp.hitCondition,
setter = function(v)
bp.hitCondition = v
end,
},
["Log Message"] = {
value = bp.logMessage,
setter = function(v)
bp.logMessage = v
end,
},
}
local menu_options = {}
for k, v in pairs(props) do
table.insert(menu_options, ("%s: %s"):format(k, v.value))
end
vim.ui.select(menu_options, {
prompt = "Edit Breakpoint",
}, function(choice)
local prompt = (tostring(choice)):gsub(":.*", "")
props[prompt].setter(vim.fn.input({
prompt = prompt,
default = props[prompt].value,
}))
-- Set breakpoint for current line, with customizations (see h:dap.set_breakpoint())
dap.set_breakpoint(bp.condition, bp.hitCondition, bp.logMessage)
end)
end
customize_bp(find_bp())
end
-- stylua: ignore
local default_keys = {
{ "<leader>dB", edit_breakpoint, desc = "Breakpoint Condition" },
{ "<leader>db", function() dap.toggle_breakpoint() end, desc = "Toggle Breakpoint" },
{ "<leader>dc", function() dap.continue() end, desc = "Run/Continue" },
{ "<leader>da", function() dap.continue({ before = get_args }) end, desc = "Run with Args" },
{ "<leader>dC", function() dap.run_to_cursor() end, desc = "Run to Cursor" },
{ "<leader>dg", function() dap.goto_() end, desc = "Go to Line (No Execute)" },
{ "<leader>di", function() dap.step_into() end, desc = "Step Into" },
{ "<leader>dj", function() dap.down() end, desc = "Down" },
{ "<leader>dk", function() dap.up() end, desc = "Up" },
{ "<leader>dl", function() dap.run_last() end, desc = "Run Last" },
{ "<leader>do", function() dap.step_out() end, desc = "Step Out" },
{ "<leader>dO", function() dap.step_over() end, desc = "Step Over" },
{ "<leader>dP", function() dap.pause() end, desc = "Pause" },
{ "<leader>dr", function() dap.repl.toggle() end, desc = "Toggle REPL" },
{ "<leader>ds", function() dap.session() end, desc = "Session" },
{ "<leader>dt", function() dap.terminate() end, desc = "Terminate" },
{ "<leader>dw", function() require("dap.ui.widgets").hover() end, desc = "Widgets" },
}
return vim.tbl_deep_extend("force", default_keys, keys)
end,
config = function() config = function()
-- load mason-nvim-dap here, after all adapters have been setup -- load mason-nvim-dap here, after all adapters have been setup