Skip to content

Commit a501f51

Browse files
committed
fix(renderer): only set diff lines on part replace
1 parent bece9f8 commit a501f51

File tree

1 file changed

+39
-1
lines changed

1 file changed

+39
-1
lines changed

lua/opencode/ui/renderer.lua

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ M._subscriptions = {}
1111
M._prev_line_count = 0
1212
M._render_state = RenderState.new()
1313
M._disable_auto_scroll = false
14+
M._last_part_formatted = { part_id = nil, formatted_data = nil }
1415

1516
local trigger_on_data_rendered = require('opencode.util').debounce(function()
1617
local cb_type = type(config.ui.output.rendering.on_data_rendered)
@@ -37,6 +38,7 @@ function M.reset()
3738
M._prev_line_count = 0
3839
M._render_state:reset()
3940
M._disable_auto_scroll = false
41+
M._last_part_formatted = { part_id = nil, formatted_data = nil }
4042

4143
output_window.clear()
4244

@@ -251,6 +253,9 @@ function M._insert_part_to_buffer(part_id, formatted_data)
251253
end
252254

253255
M._render_state:set_part(cached.part, range.line_start, range.line_end)
256+
257+
M._last_part_formatted = { part_id = part_id, formatted_data = formatted_data }
258+
254259
return true
255260
end
256261

@@ -267,11 +272,42 @@ function M._replace_part_in_buffer(part_id, formatted_data)
267272

268273
local new_lines = formatted_data.lines
269274
local new_line_count = #new_lines
275+
-- local old_line_count = cached.line_end - cached.line_start + 1
276+
277+
local old_formatted = M._last_part_formatted
278+
local can_optimize = old_formatted
279+
and old_formatted.part_id == part_id
280+
and old_formatted.formatted_data
281+
and old_formatted.formatted_data.lines
282+
283+
local lines_to_write = new_lines
284+
local write_start_line = cached.line_start
285+
286+
if can_optimize then
287+
local old_lines = old_formatted.formatted_data.lines
288+
local first_diff_line = nil
289+
290+
for i = 1, math.min(#old_lines, new_line_count) do
291+
if old_lines[i] ~= new_lines[i] then
292+
first_diff_line = i
293+
break
294+
end
295+
end
296+
297+
if not first_diff_line and new_line_count > #old_lines then
298+
first_diff_line = #old_lines + 1
299+
end
300+
301+
if first_diff_line then
302+
lines_to_write = vim.list_slice(new_lines, first_diff_line, new_line_count)
303+
write_start_line = cached.line_start + first_diff_line - 1
304+
end
305+
end
270306

271307
M._render_state:clear_actions(part_id)
272308

273309
output_window.clear_extmarks(cached.line_start - 1, cached.line_end + 1)
274-
output_window.set_lines(new_lines, cached.line_start, cached.line_end + 1)
310+
output_window.set_lines(lines_to_write, write_start_line, cached.line_end + 1)
275311

276312
local new_line_end = cached.line_start + new_line_count - 1
277313

@@ -283,6 +319,8 @@ function M._replace_part_in_buffer(part_id, formatted_data)
283319

284320
M._render_state:update_part_lines(part_id, cached.line_start, new_line_end)
285321

322+
M._last_part_formatted = { part_id = part_id, formatted_data = formatted_data }
323+
286324
return true
287325
end
288326

0 commit comments

Comments
 (0)