Skip to content

Commit 4b00596

Browse files
committed
fix(watches): ensure redraw always happens after user actions
This fixes some regressions from 0746f35, which ended up massively complicating stuff and introducing a bunch of bugs. As it turns out, dealing with the coroutine shenanigans is a lot easier than anticipated: if we are wrapping with a coroutine, there's not much to worry about. There's no need to handle call `yield` and `resume` manually, as `nvim-dap` abstracts that.
1 parent 5029906 commit 4b00596

File tree

5 files changed

+56
-98
lines changed

5 files changed

+56
-98
lines changed

lua/dap-view/actions.lua

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,7 @@ end
121121
M.add_expr = function(expr, default_expanded)
122122
local expr_ = expr or require("dap-view.util.exprs").get_current_expr()
123123
coroutine.wrap(function()
124-
local co = coroutine.running()
125-
if require("dap-view.watches.actions").add_watch_expr(expr_, default_expanded, co) then
124+
if require("dap-view.watches.actions").add_watch_expr(expr_, default_expanded) then
126125
require("dap-view.views").switch_to_view("watches")
127126
end
128127
end)()

lua/dap-view/refresher.lua

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ end
3333

3434
M.refresh_all_expressions = function()
3535
coroutine.wrap(function()
36-
local co = coroutine.running()
37-
eval.reevaluate_all_expressions(co)
36+
for expr, _ in pairs(state.watched_expressions) do
37+
M.evaluate_expression(expr, true)
38+
end
3839

3940
if state.current_section == "watches" then
4041
require("dap-view.views").switch_to_view("watches")

lua/dap-view/views/keymaps/views.lua

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ M.views_keymaps = function()
2424
require("dap.ui").trigger_actions({ mode = "first" })
2525
elseif state.current_section == "watches" then
2626
coroutine.wrap(function()
27-
local co = coroutine.running()
28-
29-
if watches_actions.expand_or_collapse(cursor_line, co) then
27+
if watches_actions.expand_or_collapse(cursor_line) then
3028
require("dap-view.views").switch_to_view("watches")
3129
end
3230
end)()
@@ -84,9 +82,7 @@ M.views_keymaps = function()
8482
vim.ui.input({ prompt = "Expression: " }, function(input)
8583
if input then
8684
coroutine.wrap(function()
87-
local co = coroutine.running()
88-
89-
if watches_actions.add_watch_expr(input, true, co) then
85+
if watches_actions.add_watch_expr(input, true) then
9086
require("dap-view.views").switch_to_view("watches")
9187
end
9288
end)()
@@ -118,9 +114,7 @@ M.views_keymaps = function()
118114
vim.ui.input({ prompt = "Expression: ", default = expression_view.expression }, function(input)
119115
if input then
120116
coroutine.wrap(function()
121-
local co = coroutine.running()
122-
123-
if watches_actions.edit_watch_expr(input, cursor_line, co) then
117+
if watches_actions.edit_watch_expr(input, cursor_line) then
124118
require("dap-view.views").switch_to_view("watches")
125119
end
126120
end)()

lua/dap-view/watches/actions.lua

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,12 @@ local M = {}
77

88
---@param expr string
99
---@param default_expanded boolean
10-
---@param co thread
11-
M.add_watch_expr = function(expr, default_expanded, co)
10+
M.add_watch_expr = function(expr, default_expanded)
1211
if #expr == 0 or not guard.expect_session() then
1312
return false
1413
end
1514

16-
eval.evaluate_expression(expr, default_expanded, co)
17-
18-
coroutine.yield(co)
15+
eval.evaluate_expression(expr, default_expanded)
1916

2017
state.expr_count = state.expr_count + 1
2118

@@ -118,8 +115,7 @@ end
118115

119116
---@param expr string
120117
---@param line number
121-
---@param co thread
122-
M.edit_watch_expr = function(expr, line, co)
118+
M.edit_watch_expr = function(expr, line)
123119
if #expr == 0 or not guard.expect_session() then
124120
return false
125121
end
@@ -131,16 +127,13 @@ M.edit_watch_expr = function(expr, line, co)
131127
return false
132128
end
133129

134-
eval.evaluate_expression(expr, expression_view.view.expanded, co)
135-
136-
coroutine.yield(co)
130+
eval.evaluate_expression(expr, expression_view.view.expanded)
137131

138132
return true
139133
end
140134

141135
---@param line number
142-
---@param co thread
143-
M.expand_or_collapse = function(line, co)
136+
M.expand_or_collapse = function(line)
144137
if not guard.expect_session() then
145138
return
146139
end
@@ -150,9 +143,7 @@ M.expand_or_collapse = function(line, co)
150143
if expression_view then
151144
expression_view.view.expanded = not expression_view.view.expanded
152145

153-
eval.evaluate_expression(expression_view.expression, true, co)
154-
155-
coroutine.yield(co)
146+
eval.evaluate_expression(expression_view.expression, true)
156147

157148
return true
158149
else
@@ -167,7 +158,7 @@ M.expand_or_collapse = function(line, co)
167158
if variable_view then
168159
variable_view.expanded = not variable_view.expanded
169160

170-
variable_view.children, variable_view.err = eval.expand_variable(reference, nil, co)
161+
variable_view.children, variable_view.err = eval.expand_variable(reference, nil)
171162

172163
return true
173164
end

lua/dap-view/watches/eval.lua

Lines changed: 42 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,66 +4,59 @@ local M = {}
44

55
---@param expression string
66
---@param default_expanded boolean
7-
---@param co thread?
8-
M.evaluate_expression = function(expression, default_expanded, co)
7+
M.evaluate_expression = function(expression, default_expanded)
98
local session = assert(require("dap").session(), "has active session")
109

11-
coroutine.wrap(function()
12-
local frame_id = session.current_frame and session.current_frame.id
13-
14-
local err, response =
15-
session:request("evaluate", { expression = expression, context = "watch", frameId = frame_id })
10+
local frame_id = session.current_frame and session.current_frame.id
1611

17-
local previous_expression_view = state.watched_expressions[expression]
12+
local err, response =
13+
session:request("evaluate", { expression = expression, context = "watch", frameId = frame_id })
1814

19-
local previous_result = previous_expression_view
20-
and previous_expression_view.response
21-
and previous_expression_view.response.result
15+
local previous_expression_view = state.watched_expressions[expression]
2216

23-
if previous_expression_view and response then
24-
previous_expression_view.updated = previous_result ~= response.result
25-
end
17+
local previous_result = previous_expression_view
18+
and previous_expression_view.response
19+
and previous_expression_view.response.result
2620

27-
if previous_expression_view and err then
28-
previous_expression_view.children = nil
29-
previous_expression_view.updated = false
30-
previous_expression_view.expanded = false
31-
end
21+
if previous_expression_view and response then
22+
previous_expression_view.updated = previous_result ~= response.result
23+
end
3224

33-
---@type dapview.ExpressionView
34-
local default_expression_view = {
35-
id = state.expr_count,
36-
response = response,
37-
err = err,
38-
updated = false,
39-
expanded = default_expanded,
40-
children = nil,
41-
}
25+
if previous_expression_view and err then
26+
previous_expression_view.children = nil
27+
previous_expression_view.updated = false
28+
previous_expression_view.expanded = false
29+
end
4230

43-
if previous_expression_view then
44-
previous_expression_view.response = response
45-
previous_expression_view.err = err
46-
end
31+
---@type dapview.ExpressionView
32+
local default_expression_view = {
33+
id = state.expr_count,
34+
response = response,
35+
err = err,
36+
updated = false,
37+
expanded = default_expanded,
38+
children = nil,
39+
}
40+
41+
if previous_expression_view then
42+
previous_expression_view.response = response
43+
previous_expression_view.err = err
44+
end
4745

48-
---@type dapview.ExpressionView
49-
local new_expression_view = previous_expression_view or default_expression_view
46+
---@type dapview.ExpressionView
47+
local new_expression_view = previous_expression_view or default_expression_view
5048

51-
if new_expression_view.expanded then
52-
local variables_reference = response and response.variablesReference
49+
if new_expression_view.expanded then
50+
local variables_reference = response and response.variablesReference
5351

54-
if variables_reference and variables_reference > 0 then
55-
new_expression_view.children = M.expand_variable(variables_reference, new_expression_view.children)
56-
else
57-
new_expression_view.children = nil
58-
end
52+
if variables_reference and variables_reference > 0 then
53+
new_expression_view.children = M.expand_variable(variables_reference, new_expression_view.children)
54+
else
55+
new_expression_view.children = nil
5956
end
57+
end
6058

61-
state.watched_expressions[expression] = new_expression_view
62-
63-
if co then
64-
coroutine.resume(co)
65-
end
66-
end)()
59+
state.watched_expressions[expression] = new_expression_view
6760
end
6861

6962
---@param expr string
@@ -91,8 +84,7 @@ end
9184

9285
---@param variables_reference number
9386
---@param previous_expansion_result dapview.VariableView[]?
94-
---@param co thread?
95-
M.expand_variable = function(variables_reference, previous_expansion_result, co)
87+
M.expand_variable = function(variables_reference, previous_expansion_result)
9688
local session = assert(require("dap").session(), "has active session")
9789

9890
local frame_id = session.current_frame and session.current_frame.id
@@ -152,34 +144,15 @@ M.expand_variable = function(variables_reference, previous_expansion_result, co)
152144
new_variable_view.children, new_variable_view.err =
153145
M.expand_variable(variables_reference_, new_variable_view.children)
154146
else
155-
-- We have to reset the children if the variable is no longer, otherwise it retains the old value indefinely
147+
-- We have to reset the children if the variable is no longer, otherwise it retains the old value indefinitely
156148
new_variable_view.children = nil
157149
end
158150
end
159151

160152
varible_views[k] = new_variable_view
161153
end
162154

163-
if co then
164-
coroutine.resume(co)
165-
end
166-
167155
return #varible_views > 0 and varible_views or nil, err
168156
end
169157

170-
---@param co thread?
171-
M.reevaluate_all_expressions = function(co)
172-
local i = 0
173-
local size = vim.tbl_count(state.watched_expressions)
174-
175-
for expr, _ in pairs(state.watched_expressions) do
176-
i = i + 1
177-
178-
-- This assumes that the last evaluation will be the last one to fnish, but I'm not sure that's the case?
179-
M.evaluate_expression(expr, true, i == size and co or nil)
180-
end
181-
182-
coroutine.yield(co)
183-
end
184-
185158
return M

0 commit comments

Comments
 (0)