Add data breakpoints

Early WIP, picking up https://github.com/mfussenegger/nvim-dap/pull/134
but implemented on top of widget & entity

- [ ] Refine user API
- [ ] Variable render should indicate if there is an active data breakpoint
- [ ] Handle persistence (Do they go into dap.breakpoints, new module, or are part of the session)
- [ ] What goes into entity and what into session
This commit is contained in:
Mathias Fussenegger 2021-12-02 16:21:54 +01:00
parent 16c22742df
commit 7f94148c69
3 changed files with 81 additions and 0 deletions

View file

@ -1,6 +1,7 @@
local api = vim.api
local non_empty = require('dap.utils').non_empty
local data_breakpoints = {}
local bp_by_sign = {}
local ns = 'dap_breakpoints'
local M = {}
@ -128,6 +129,11 @@ end
function M.clear()
vim.fn.sign_unplace(ns)
bp_by_sign = {}
data_breakpoints = {}
end
function M.set_data_bp(bp)
end

View file

@ -150,6 +150,70 @@ local function set_expression(_, item, _, context)
end
local function get_parent(var, variables)
for _, v in pairs(variables) do
local children = variable.get_children(v)
if children then
if vim.tbl_contains(children, var) then
return v
end
local parent = get_parent(var, children)
if parent then
return parent
end
end
end
return nil
end
local function set_data_breakpoint(_, item, _, context)
local session = require('dap').session()
if not session then
utils.notify('No active session, cannot set data breakpoint')
return
end
if not session.current_frame then
utils.notify('Session has no active frame, cannot set data breakpoint')
return
end
local parent = get_parent(item, session.current_frame.scopes)
if not parent then
utils.notify(string.format(
"Cannot set data breakpoint on %s, couldn't find its parent container",
item.name
))
return
end
local params = {
variablesReference = parent.variablesReference,
name = item.name,
}
local view = context.view
local close_view = view and vim.bo.bufhidden == 'wipe'
session:request('dataBreakpointInfo', params, function(err, resp)
if err then
utils.notify(err.message, vim.log.levels.WARN)
return
end
if not resp or not resp.dataId then
utils.notify('Cannot set data breakpoint for ' .. item.name, vim.log.levels.WARN)
return
end
require('dap.data_breakpoints').add(resp)
session:set_data_breakpoints(function(err0)
if err0 then
utils.notify(err0.message, vim.log.levels.WARN)
return
end
if close_view then
view.close()
end
end)
end)
end
variable.tree_spec = {
get_key = variable.get_key,
render_parent = variable.render_parent,
@ -170,6 +234,9 @@ variable.tree_spec = {
elseif capabilities.supportsSetVariable then
table.insert(result, { label = 'Set variable', fn = set_variable, })
end
if capabilities.supportsDataBreakpoints then
table.insert(result, { label = 'Set data breakpoint', fn = set_data_breakpoint, })
end
return result
end
}

View file

@ -427,6 +427,14 @@ function Session:_goto(line, source, col)
end
function Session:set_data_breakpoints(on_done)
local params = {
breakpoints = breakpoints.get_data_breakpoints()
}
self:request('setDataBreakpoints', params, on_done)
end
do
local function notify_if_missing_capability(bufnr, bps, capabilities)
for _, bp in pairs(bps) do