perf(sidebar): update the buffer more efficiently (#724)

This commit is contained in:
yetone 2024-10-15 12:30:20 +08:00 committed by GitHub
parent 86ba5a468b
commit 8c28e285ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 44 additions and 4 deletions

View File

@ -85,8 +85,6 @@ M.stream = function(opts)
:filter(function(k) return k ~= "" end)
:totable()
Utils.debug("user prompts:", user_prompts)
---@type AvantePromptOptions
local code_opts = {
system_prompt = Config.system_prompt,

View File

@ -1048,7 +1048,7 @@ function Sidebar:update_content(content, opts)
if not self.result or not self.result.bufnr or not api.nvim_buf_is_valid(self.result.bufnr) then return end
local lines = vim.split(content, "\n")
Utils.unlock_buf(self.result.bufnr)
api.nvim_buf_set_lines(self.result.bufnr, 0, -1, false, lines)
Utils.update_buffer_content(self.result.bufnr, lines)
Utils.lock_buf(self.result.bufnr)
api.nvim_set_option_value("filetype", "Avante", { buf = self.result.bufnr })
if opts.focus and not self:is_focused_on_result() then
@ -1332,7 +1332,7 @@ function Sidebar:create_input(opts)
end
-- Execute when the stream request is actually completed
self:update_content("\n\n**Generation complete!** Please review the code suggestions above.", {
self:update_content("\n\n**Generation complete!** Please review the code suggestions above.\n", {
stream = true,
scroll = true,
callback = function() api.nvim_exec_autocmds("User", { pattern = VIEW_BUFFER_UPDATED_PATTERN }) end,

View File

@ -682,4 +682,46 @@ function M.create_new_buffer_with_file(filepath)
return buf
end
---@param bufnr integer
---@param new_lines string[]
---@return { start_line: integer, end_line: integer, content: string[] }[]
local function get_buffer_content_diffs(bufnr, new_lines)
local old_lines = api.nvim_buf_get_lines(bufnr, 0, -1, false)
local diffs = {}
local prev_diff_idx = nil
for i, line in ipairs(new_lines) do
if line ~= old_lines[i] then
if prev_diff_idx == nil then prev_diff_idx = i end
else
if prev_diff_idx ~= nil then
local content = vim.list_slice(new_lines, prev_diff_idx, i - 1)
table.insert(diffs, { start_line = prev_diff_idx, end_line = i, content = content })
prev_diff_idx = nil
end
end
end
if prev_diff_idx ~= nil then
table.insert(
diffs,
{ start_line = prev_diff_idx, end_line = #new_lines + 1, content = vim.list_slice(new_lines, prev_diff_idx) }
)
end
if #new_lines < #old_lines then
table.insert(diffs, { start_line = #new_lines + 1, end_line = #old_lines + 1, content = {} })
end
table.sort(diffs, function(a, b) return a.start_line > b.start_line end)
return diffs
end
--- Update the buffer content more efficiently by only updating the changed lines
---@param bufnr integer
---@param new_lines string[]
function M.update_buffer_content(bufnr, new_lines)
local diffs = get_buffer_content_diffs(bufnr, new_lines)
if #diffs == 0 then return end
for _, diff in ipairs(diffs) do
api.nvim_buf_set_lines(bufnr, diff.start_line - 1, diff.end_line - 1, false, diff.content)
end
end
return M