Skip to content

Commit 999a36d

Browse files
committed
refactor(renderer): address review feedback - extract folds_equal, simplify update_part_folds loop
- Extract folds_equal() helper function with nil-guard - Simplify update_part_folds loop by assigning ctx.part_folds first - Add 3 test cases for update_part_folds: absolute range computation, unchanged fold short-circuit, and multi-part fold merging
1 parent 34e9f8f commit 999a36d

2 files changed

Lines changed: 79 additions & 30 deletions

File tree

lua/opencode/ui/renderer/buffer.lua

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,15 @@ function M.set_all_folds()
657657
output_window.set_folds(all_folds)
658658
end
659659

660+
local function folds_equal(a, b)
661+
if not a or not b then return false end
662+
if #a ~= #b then return false end
663+
for i = 1, #a do
664+
if a[i].from ~= b[i].from or a[i].to ~= b[i].to then return false end
665+
end
666+
return true
667+
end
668+
660669
---Update folds for a single part during streaming, avoiding a full rebuild.
661670
---@param part_id string
662671
function M.update_part_folds(part_id)
@@ -679,41 +688,17 @@ function M.update_part_folds(part_id)
679688
})
680689
end
681690

682-
local old_folds = ctx.part_folds[part_id]
683-
if old_folds and #old_folds == #new_folds then
684-
local same = true
685-
for i = 1, #new_folds do
686-
if new_folds[i].from ~= old_folds[i].from or new_folds[i].to ~= old_folds[i].to then
687-
same = false
688-
break
689-
end
690-
end
691-
if same then
692-
return
693-
end
691+
if folds_equal(ctx.part_folds[part_id], new_folds) then
692+
return
694693
end
695694

695+
ctx.part_folds[part_id] = new_folds
696696
local new_global = {}
697-
local found = false
698-
for pid, pf in pairs(ctx.part_folds) do
699-
if pid == part_id then
700-
found = true
701-
for _, nf in ipairs(new_folds) do
702-
table.insert(new_global, nf)
703-
end
704-
else
705-
for _, of in ipairs(pf) do
706-
table.insert(new_global, of)
707-
end
697+
for _, pf in pairs(ctx.part_folds) do
698+
for _, f in ipairs(pf) do
699+
table.insert(new_global, f)
708700
end
709701
end
710-
if not found then
711-
for _, nf in ipairs(new_folds) do
712-
table.insert(new_global, nf)
713-
end
714-
end
715-
716-
ctx.part_folds[part_id] = new_folds
717702
ctx.global_folds = new_global
718703
output_window.set_folds(new_global)
719704
end

tests/unit/renderer_buffer_spec.lua

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,67 @@ describe('renderer.buffer extmarks', function()
126126
assert_called_before(call_order, 'clear_extmarks', 'set_lines')
127127
end)
128128
end)
129+
130+
describe('update_part_folds', function()
131+
local set_folds_stub
132+
133+
before_each(function()
134+
ctx:reset()
135+
set_folds_stub = stub(output_window, 'set_folds')
136+
ctx.global_folds = {}
137+
ctx.part_folds = {}
138+
end)
139+
140+
after_each(function()
141+
set_folds_stub:revert()
142+
ctx:reset()
143+
end)
144+
145+
it('computes absolute fold ranges for a single part', function()
146+
ctx.formatted_parts['part_a'] = {
147+
lines = { 'title', '', 'content', 'more' },
148+
fold_ranges = { { from = 1, to = 4 } },
149+
}
150+
ctx.render_state:set_part({ id = 'part_a', messageID = 'msg_1', type = 'text' }, 10, 14)
151+
152+
buffer.update_part_folds('part_a')
153+
154+
assert.stub(set_folds_stub).was_called_with({
155+
{ from = 10, to = 13 },
156+
})
157+
end)
158+
159+
it('skips set_folds when fold ranges have not changed', function()
160+
ctx.formatted_parts['part_a'] = {
161+
lines = { 'title', '', 'content', 'more' },
162+
fold_ranges = { { from = 1, to = 4 } },
163+
}
164+
ctx.render_state:set_part({ id = 'part_a', messageID = 'msg_1', type = 'text' }, 10, 14)
165+
166+
buffer.update_part_folds('part_a')
167+
set_folds_stub:clear()
168+
169+
buffer.update_part_folds('part_a')
170+
171+
assert.stub(set_folds_stub).was_not_called()
172+
end)
173+
174+
it('merges existing folds from other parts', function()
175+
ctx.part_folds['part_b'] = { { from = 5, to = 8 } }
176+
ctx.global_folds = { { from = 5, to = 8 } }
177+
178+
ctx.formatted_parts['part_a'] = {
179+
lines = { 'title', '', 'content', 'more' },
180+
fold_ranges = { { from = 1, to = 4 } },
181+
}
182+
ctx.render_state:set_part({ id = 'part_a', messageID = 'msg_1', type = 'text' }, 10, 14)
183+
184+
buffer.update_part_folds('part_a')
185+
186+
assert.stub(set_folds_stub).was_called()
187+
assert.stub(set_folds_stub).was_called_with({
188+
{ from = 5, to = 8 },
189+
{ from = 10, to = 13 },
190+
})
191+
end)
192+
end)

0 commit comments

Comments
 (0)