1+ local state = require (" dap-view.state" )
2+
13local M = {}
24
5+ --- @param variables_reference number
6+ --- @param frame_id ? number
7+ local eval_variables = function (variables_reference , frame_id )
8+ local session = assert (require (" dap" ).session (), " has active session" )
9+
10+ local err , result = session :request (
11+ " variables" ,
12+ { variablesReference = variables_reference , context = " watch" , frameId = frame_id }
13+ )
14+
15+ local response = err and tostring (err ) or result and result .variables
16+
17+ --[[ @type {variable?: dap.Variable, updated?: boolean}[] | string]]
18+ local variables = type (response ) == " string" and response or {}
19+
20+ local original = state .variables_by_reference [variables_reference ]
21+
22+ -- Lua's type checking is a lackluster
23+ if type (variables ) ~= " string" and type (response ) ~= " string" then
24+ for k , var in pairs (response or {}) do
25+ local updated = type (original ) == " table" and original [k ].variable .value ~= var .value or false
26+ table.insert (variables , { variable = var , updated = updated })
27+ end
28+ end
29+
30+ state .variables_by_reference [variables_reference ] = variables
31+ end
32+
333--- @param expr string
4- --- @param callback fun ( result : string ): nil
5- M .eval_expr = function (expr , callback )
34+ M .eval_expr = function (expr )
635 local session = assert (require (" dap" ).session (), " has active session" )
736
837 coroutine.wrap (function ()
@@ -11,35 +40,37 @@ M.eval_expr = function(expr, callback)
1140 local err , result =
1241 session :request (" evaluate" , { expression = expr , context = " watch" , frameId = frame_id })
1342
14- local expr_result = result and result .result or err and tostring (err ):gsub (" %s+" , " " ) or " "
43+ local original = state .watched_expressions [expr ] and state .watched_expressions [expr ].response .result
44+ local response = err and tostring (err ) or result
45+ local updated = original and response and original ~= response .result
46+ state .watched_expressions [expr ] = { response = response , updated = updated }
1547
16- -- TODO currently, we only check for variables reference for the top level expression
17- -- It would be nice to expose functionality to let the user control the depth
18- -- This could be a config parameter (eg, base depth) but could also extend with an action (BFS)
1948 local variables_reference = result and result .variablesReference
2049 if variables_reference and variables_reference > 0 then
21- local enhanced_expr_result = { expr_result }
22-
23- local var_ref_err , var_ref_result = session :request (
24- " variables" ,
25- { variablesReference = variables_reference , context = " watch" , frameId = frame_id }
26- )
27-
28- if var_ref_err then
29- table.insert (enhanced_expr_result , tostring (err ))
30- elseif var_ref_result then
31- for _ , k in pairs (var_ref_result .variables ) do
32- table.insert (enhanced_expr_result , " \t " .. k .name .. " = " .. k .value )
33- end
34- end
35-
36- local final_result = table.concat (enhanced_expr_result , " \n " )
37-
38- callback (final_result )
39- else
40- callback (expr_result )
50+ eval_variables (variables_reference , frame_id )
4151 end
4252 end )()
4353end
4454
55+ --- @param expr string
56+ M .copy_expr = function (expr )
57+ local session = assert (require (" dap" ).session (), " has active session" )
58+
59+ if session .capabilities .supportsClipboardContext then
60+ coroutine.wrap (function ()
61+ local frame_id = session .current_frame and session .current_frame .id
62+
63+ local err , result =
64+ session :request (" evaluate" , { expression = expr , context = " clipboard" , frameId = frame_id })
65+
66+ if err == nil and result then
67+ -- TODO uses system clipboard, could be a parameter instead
68+ vim .fn .setreg (" +" , result .result )
69+ end
70+ end )()
71+ else
72+ vim .notify (" Adapter doesn't support clipboard evaluation" )
73+ end
74+ end
75+
4576return M
0 commit comments