diff --git a/lua/dap/breakpoints.lua b/lua/dap/breakpoints.lua index 9d4afa55..df3f5bf8 100644 --- a/lua/dap/breakpoints.lua +++ b/lua/dap/breakpoints.lua @@ -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 diff --git a/lua/dap/entity.lua b/lua/dap/entity.lua index fb3bc593..155745bf 100644 --- a/lua/dap/entity.lua +++ b/lua/dap/entity.lua @@ -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 } diff --git a/lua/dap/session.lua b/lua/dap/session.lua index 43cb96b7..f6222a37 100644 --- a/lua/dap/session.lua +++ b/lua/dap/session.lua @@ -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