diff --git a/lua/avante/llm.lua b/lua/avante/llm.lua index c1a2e3a..21acddf 100644 --- a/lua/avante/llm.lua +++ b/lua/avante/llm.lua @@ -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, diff --git a/lua/avante/sidebar.lua b/lua/avante/sidebar.lua index 9afbcfc..8f74f5b 100644 --- a/lua/avante/sidebar.lua +++ b/lua/avante/sidebar.lua @@ -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, diff --git a/lua/avante/utils/init.lua b/lua/avante/utils/init.lua index 47f8e6a..d9d9de3 100644 --- a/lua/avante/utils/init.lua +++ b/lua/avante/utils/init.lua @@ -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