From 9fbe0256f277a940fa61dce127129c1e8a3916a0 Mon Sep 17 00:00:00 2001 From: yetone Date: Tue, 5 Nov 2024 21:02:38 +0800 Subject: [PATCH] feat: keep the history content in the resp buffer (#807) --- lua/avante/path.lua | 14 ++++++++++++-- lua/avante/sidebar.lua | 38 +++++++++++++++++++++++++++----------- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/lua/avante/path.lua b/lua/avante/path.lua index e735803..7b1249b 100644 --- a/lua/avante/path.lua +++ b/lua/avante/path.lua @@ -1,5 +1,6 @@ local fn, api = vim.fn, vim.api local Utils = require("avante.utils") +local LRUCache = require("avante.utils.lru_cache") local Path = require("plenary.path") local Scan = require("plenary.scandir") local Config = require("avante.config") @@ -27,6 +28,8 @@ end ---@param mode LlmMode H.get_mode_file = function(mode) return string.format("custom.%s.avanterules", mode) end +local history_file_cache = LRUCache:new(12) + -- History path local History = {} @@ -39,11 +42,16 @@ History.get = function(bufnr) return Path:new(Config.history.storage_path):joinp ---@param bufnr integer History.load = function(bufnr) local history_file = History.get(bufnr) + local cached_key = tostring(history_file:absolute()) + local cached_value = history_file_cache:get(cached_key) + if cached_value ~= nil then return cached_value end + local value = {} if history_file:exists() then local content = history_file:read() - return content ~= nil and vim.json.decode(content) or {} + value = content ~= nil and vim.json.decode(content) or {} end - return {} + history_file_cache:set(cached_key, value) + return value end -- Saves the chat history for the given buffer. @@ -51,7 +59,9 @@ end ---@param history table History.save = vim.schedule_wrap(function(bufnr, history) local history_file = History.get(bufnr) + local cached_key = tostring(history_file:absolute()) history_file:write(vim.json.encode(history), "w") + history_file_cache:set(cached_key, history) end) P.history = History diff --git a/lua/avante/sidebar.lua b/lua/avante/sidebar.lua index 0cfd126..0639a74 100644 --- a/lua/avante/sidebar.lua +++ b/lua/avante/sidebar.lua @@ -1022,10 +1022,14 @@ local function delete_last_n_chars(bufnr, n) end ---@param content string concatenated content of the buffer ----@param opts? {focus?: boolean, stream?: boolean, scroll?: boolean, backspace?: integer, callback?: fun(): nil} whether to focus the result view +---@param opts? {focus?: boolean, scroll?: boolean, backspace?: integer, ignore_history?: boolean, callback?: fun(): nil} whether to focus the result view function Sidebar:update_content(content, opts) if not self.result or not self.result.bufnr then return end opts = vim.tbl_deep_extend("force", { focus = true, scroll = true, stream = false, callback = nil }, opts or {}) + if not opts.ignore_history then + local chat_history = Path.history.load(self.code.bufnr) + content = self:get_history_content(chat_history) .. "---\n\n" .. content + end if opts.stream then local scroll_to_bottom = function() local last_line = api.nvim_buf_line_count(self.result.bufnr) @@ -1117,7 +1121,7 @@ function Sidebar:get_layout() return vim.tbl_contains({ "left", "right" }, calculate_config_window_position()) and "vertical" or "horizontal" end -function Sidebar:update_content_with_history(history) +function Sidebar:get_history_content(history) local content = "" for idx, entry in ipairs(history) do local prefix = @@ -1126,7 +1130,12 @@ function Sidebar:update_content_with_history(history) content = content .. entry.response .. "\n\n" if idx < #history then content = content .. "---\n\n" end end - self:update_content(content) + return content +end + +function Sidebar:update_content_with_history(history) + local content = self:get_history_content(history) + self:update_content(content, { ignore_history = true }) end ---@return string, integer @@ -1344,11 +1353,11 @@ function Sidebar:create_input(opts) local cur_displayed_response = generate_display_content(transformed) if is_first_chunk then is_first_chunk = false - self:update_content(content_prefix .. chunk, { stream = false, scroll = true }) + self:update_content(content_prefix .. chunk, { scroll = true }) return end local suffix = get_display_content_suffix(transformed) - self:update_content(content_prefix .. cur_displayed_response .. suffix, { stream = false, scroll = true }) + self:update_content(content_prefix .. cur_displayed_response .. suffix, { scroll = true }) vim.schedule(function() vim.cmd("redraw") end) displayed_response = cur_displayed_response end @@ -1356,16 +1365,23 @@ function Sidebar:create_input(opts) ---@type AvanteCompleteParser local on_complete = function(err) if err ~= nil then - self:update_content("\n\nError: " .. vim.inspect(err), { stream = true, scroll = true }) + self:update_content( + content_prefix .. displayed_response .. "\n\nError: " .. vim.inspect(err), + { scroll = true } + ) return end -- Execute when the stream request is actually completed - 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, - }) + self:update_content( + content_prefix + .. displayed_response + .. "\n\n**Generation complete!** Please review the code suggestions above.\n", + { + scroll = true, + callback = function() api.nvim_exec_autocmds("User", { pattern = VIEW_BUFFER_UPDATED_PATTERN }) end, + } + ) vim.defer_fn(function() if self.result and self.result.winid and api.nvim_win_is_valid(self.result.winid) then