Skip to content

Commit

Permalink
perf(sidebar): update the buffer more efficiently (yetone#724)
Browse files Browse the repository at this point in the history
  • Loading branch information
yetone authored Oct 15, 2024
1 parent 86ba5a4 commit 8c28e28
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 4 deletions.
2 changes: 0 additions & 2 deletions lua/avante/llm.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions lua/avante/sidebar.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
42 changes: 42 additions & 0 deletions lua/avante/utils/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 8c28e28

Please sign in to comment.