perf(sidebar): update the buffer more efficiently (#724)
This commit is contained in:
parent
86ba5a468b
commit
8c28e285ea
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user