From 1fdb1a7b84f6a4caa3ae3a1d2bb7d2472efe0869 Mon Sep 17 00:00:00 2001 From: yetone Date: Tue, 15 Apr 2025 20:16:13 +0800 Subject: [PATCH] fix: send the latest file content each time (#1879) --- lua/avante/llm.lua | 18 +++++++++++- lua/avante/llm_tools/helpers.lua | 26 ++++++++++++++++++ lua/avante/llm_tools/init.lua | 41 +++++++++++++++------------- lua/avante/llm_tools/insert.lua | 2 ++ lua/avante/llm_tools/str_replace.lua | 2 ++ lua/avante/llm_tools/undo_edit.lua | 10 ++----- lua/avante/llm_tools/view.lua | 7 ++--- lua/avante/sidebar.lua | 6 ++-- lua/avante/types.lua | 1 + 9 files changed, 78 insertions(+), 35 deletions(-) diff --git a/lua/avante/llm.lua b/lua/avante/llm.lua index 50c75d9..2ba5b9c 100644 --- a/lua/avante/llm.lua +++ b/lua/avante/llm.lua @@ -184,10 +184,26 @@ function M.generate_prompts(opts) local system_info = Utils.get_system_info() + local selected_files = opts.selected_files or {} + + if opts.selected_filepaths then + for _, filepath in ipairs(opts.selected_filepaths) do + local lines, error = Utils.read_file_from_buf_or_disk(filepath) + lines = lines or {} + local filetype = Utils.get_filetype(filepath) + if error ~= nil then + Utils.error("error reading file: " .. error) + else + local content = table.concat(lines, "\n") + table.insert(selected_files, { path = filepath, content = content, file_type = filetype }) + end + end + end + local template_opts = { ask = opts.ask, -- TODO: add mode without ask instruction code_lang = opts.code_lang, - selected_files = opts.selected_files, + selected_files = selected_files, selected_code = opts.selected_code, recently_viewed_files = opts.recently_viewed_files, project_context = opts.project_context, diff --git a/lua/avante/llm_tools/helpers.lua b/lua/avante/llm_tools/helpers.lua index 3fe523b..8e4e214 100644 --- a/lua/avante/llm_tools/helpers.lua +++ b/lua/avante/llm_tools/helpers.lua @@ -91,6 +91,32 @@ function M.already_in_context(path) return false end +---@param path string +---@param session_ctx table +---@return boolean +function M.already_viewed(path, session_ctx) + local view_history = session_ctx.view_history or {} + local uniform_path = Utils.uniform_path(path) + if view_history[uniform_path] then return true end + return false +end + +---@param path string +---@param session_ctx table +function M.mark_as_viewed(path, session_ctx) + local view_history = session_ctx.view_history or {} + local uniform_path = Utils.uniform_path(path) + view_history[uniform_path] = true + session_ctx.view_history = view_history +end + +function M.mark_as_not_viewed(path, session_ctx) + local view_history = session_ctx.view_history or {} + local uniform_path = Utils.uniform_path(path) + view_history[uniform_path] = nil + session_ctx.view_history = view_history +end + ---@param abs_path string ---@return integer bufnr ---@return string | nil error diff --git a/lua/avante/llm_tools/init.lua b/lua/avante/llm_tools/init.lua index 08e616a..b968e8a 100644 --- a/lua/avante/llm_tools/init.lua +++ b/lua/avante/llm_tools/init.lua @@ -104,14 +104,17 @@ function M.rename_file(opts, on_log, on_complete) end if Path:new(new_abs_path):exists() then return false, "File already exists: " .. new_abs_path end if not on_complete then return false, "on_complete not provided" end - Helpers.confirm("Are you sure you want to rename the file: " .. abs_path .. " to: " .. new_abs_path, function(ok) - if not ok then - on_complete(false, "User canceled") - return + Helpers.confirm( + "Are you sure you want to rename the file: " .. abs_path .. " to: " .. new_abs_path, + function(ok, reason) + if not ok then + on_complete(false, "User declined, reason: " .. (reason or "unknown")) + return + end + os.rename(abs_path, new_abs_path) + on_complete(true, nil) end - os.rename(abs_path, new_abs_path) - on_complete(true, nil) - end) + ) end ---@type AvanteLLMToolFunc<{ rel_path: string, new_rel_path: string }> @@ -137,9 +140,9 @@ function M.delete_file(opts, on_log, on_complete) if not Path:new(abs_path):exists() then return false, "File not found: " .. abs_path end if not Path:new(abs_path):is_file() then return false, "Path is not a file: " .. abs_path end if not on_complete then return false, "on_complete not provided" end - Helpers.confirm("Are you sure you want to delete the file: " .. abs_path, function(ok) + Helpers.confirm("Are you sure you want to delete the file: " .. abs_path, function(ok, reason) if not ok then - on_complete(false, "User canceled") + on_complete(false, "User declined, reason: " .. (reason or "unknown")) return end if on_log then on_log("Deleting file: " .. abs_path) end @@ -154,9 +157,9 @@ function M.create_dir(opts, on_log, on_complete) if not Helpers.has_permission_to_access(abs_path) then return false, "No permission to access path: " .. abs_path end if Path:new(abs_path):exists() then return false, "Directory already exists: " .. abs_path end if not on_complete then return false, "on_complete not provided" end - Helpers.confirm("Are you sure you want to create the directory: " .. abs_path, function(ok) + Helpers.confirm("Are you sure you want to create the directory: " .. abs_path, function(ok, reason) if not ok then - on_complete(false, "User canceled") + on_complete(false, "User declined, reason: " .. (reason or "unknown")) return end if on_log then on_log("Creating directory: " .. abs_path) end @@ -179,9 +182,9 @@ function M.rename_dir(opts, on_log, on_complete) if not on_complete then return false, "on_complete not provided" end Helpers.confirm( "Are you sure you want to rename directory " .. abs_path .. " to " .. new_abs_path .. "?", - function(ok) + function(ok, reason) if not ok then - on_complete(false, "User canceled") + on_complete(false, "User declined, reason: " .. (reason or "unknown")) return end if on_log then on_log("Renaming directory: " .. abs_path .. " to " .. new_abs_path) end @@ -198,9 +201,9 @@ function M.delete_dir(opts, on_log, on_complete) if not Path:new(abs_path):exists() then return false, "Directory not found: " .. abs_path end if not Path:new(abs_path):is_dir() then return false, "Path is not a directory: " .. abs_path end if not on_complete then return false, "on_complete not provided" end - Helpers.confirm("Are you sure you want to delete the directory: " .. abs_path, function(ok) + Helpers.confirm("Are you sure you want to delete the directory: " .. abs_path, function(ok, reason) if not ok then - on_complete(false, "User canceled") + on_complete(false, "User declined, reason: " .. (reason or "unknown")) return end if on_log then on_log("Deleting directory: " .. abs_path) end @@ -462,9 +465,9 @@ function M.git_commit(opts, on_log, on_complete) if not on_complete then return false, "on_complete not provided" end -- Confirm with user - Helpers.confirm("Are you sure you want to commit with message:\n" .. full_commit_msg, function(ok) + Helpers.confirm("Are you sure you want to commit with message:\n" .. full_commit_msg, function(ok, reason) if not ok then - on_complete(false, "User canceled") + on_complete(false, "User declined, reason: " .. (reason or "unknown")) return end -- Stage changes if scope is provided @@ -530,9 +533,9 @@ function M.python(opts, on_log, on_complete) .. abs_path .. "`?\n" .. opts.code, - function(ok) + function(ok, reason) if not ok then - on_complete(nil, "User canceled") + on_complete(nil, "User declined, reason: " .. (reason or "unknown")) return end if vim.fn.executable("docker") == 0 then diff --git a/lua/avante/llm_tools/insert.lua b/lua/avante/llm_tools/insert.lua index 32abcc8..5d599fd 100644 --- a/lua/avante/llm_tools/insert.lua +++ b/lua/avante/llm_tools/insert.lua @@ -84,6 +84,8 @@ function M.func(opts, on_log, on_complete, session_ctx) return end vim.api.nvim_buf_set_lines(bufnr, opts.insert_line, opts.insert_line, false, new_lines) + vim.api.nvim_buf_call(bufnr, function() vim.cmd("noautocmd write") end) + if session_ctx then Helpers.mark_as_not_viewed(opts.path, session_ctx) end on_complete(true, nil) end, { focus = true }, session_ctx) end diff --git a/lua/avante/llm_tools/str_replace.lua b/lua/avante/llm_tools/str_replace.lua index 924eb5c..e593590 100644 --- a/lua/avante/llm_tools/str_replace.lua +++ b/lua/avante/llm_tools/str_replace.lua @@ -148,6 +148,7 @@ function M.func(opts, on_log, on_complete, session_ctx) on_complete(false, "User canceled") return end + if session_ctx then Helpers.mark_as_not_viewed(opts.path, session_ctx) end on_complete(true, nil) end, }) @@ -163,6 +164,7 @@ function M.func(opts, on_log, on_complete, session_ctx) end vim.api.nvim_buf_set_lines(bufnr, start_line - 1, end_line, false, new_lines) vim.api.nvim_buf_call(bufnr, function() vim.cmd("noautocmd write") end) + if session_ctx then Helpers.mark_as_not_viewed(opts.path, session_ctx) end on_complete(true, nil) end, { focus = not Config.behaviour.auto_focus_on_diff_view }, session_ctx) end diff --git a/lua/avante/llm_tools/undo_edit.lua b/lua/avante/llm_tools/undo_edit.lua index aaa20e0..75ce5b6 100644 --- a/lua/avante/llm_tools/undo_edit.lua +++ b/lua/avante/llm_tools/undo_edit.lua @@ -48,19 +48,15 @@ function M.func(opts, on_log, on_complete, session_ctx) if not Path:new(abs_path):is_file() then return false, "Path is not a file: " .. abs_path end local bufnr, err = Helpers.get_bufnr(abs_path) if err then return false, err end - local current_winid = vim.api.nvim_get_current_win() local winid = Utils.get_winid(bufnr) - vim.api.nvim_set_current_win(winid) - vim.api.nvim_set_current_win(current_winid) Helpers.confirm("Are you sure you want to undo edit this file?", function(ok, reason) if not ok then on_complete(false, "User declined, reason: " .. (reason or "unknown")) return end - vim.api.nvim_set_current_win(winid) - -- run undo - vim.cmd("undo") - vim.api.nvim_set_current_win(current_winid) + vim.api.nvim_win_call(winid, function() vim.cmd("noautocmd undo") end) + vim.api.nvim_buf_call(bufnr, function() vim.cmd("noautocmd write") end) + if session_ctx then Helpers.mark_as_not_viewed(opts.path, session_ctx) end on_complete(true, nil) end, { focus = true }, session_ctx) end diff --git a/lua/avante/llm_tools/view.lua b/lua/avante/llm_tools/view.lua index a049c6c..6d0f909 100644 --- a/lua/avante/llm_tools/view.lua +++ b/lua/avante/llm_tools/view.lua @@ -81,14 +81,11 @@ function M.func(opts, on_log, on_complete, session_ctx) return end if session_ctx then - local view_history = session_ctx.view_history or {} - local uniform_path = Utils.uniform_path(opts.path) - if view_history[uniform_path] then + if Helpers.already_viewed(opts.path, session_ctx) then on_complete(nil, "Ooooops! You have already viewed this file! Why you are trying to read it again?") return end - view_history[uniform_path] = true - session_ctx.view_history = view_history + Helpers.mark_as_viewed(opts.path, session_ctx) end local abs_path = Helpers.get_abs_path(opts.path) if not Helpers.has_permission_to_access(abs_path) then return false, "No permission to access path: " .. abs_path end diff --git a/lua/avante/sidebar.lua b/lua/avante/sidebar.lua index 7b5db64..f2aefd7 100644 --- a/lua/avante/sidebar.lua +++ b/lua/avante/sidebar.lua @@ -2472,8 +2472,6 @@ function Sidebar:create_input_container(opts) local project_context = mentions.enable_project_context and file_ext and RepoMap.get_repo_map(file_ext) or nil - local selected_files_contents = self.file_selector:get_selected_files_contents() or {} - local diagnostics = nil if mentions.enable_diagnostics then if self.code ~= nil and self.code.bufnr ~= nil and self.code.selection ~= nil then @@ -2530,11 +2528,13 @@ function Sidebar:create_input_container(opts) if Config.behaviour.enable_claude_text_editor_tool_mode then mode = "claude-text-editor-tool" end + local selected_filepaths = self.file_selector.selected_filepaths or {} + ---@type AvanteGeneratePromptsOptions local prompts_opts = { ask = opts.ask or true, project_context = vim.json.encode(project_context), - selected_files = selected_files_contents, + selected_filepaths = selected_filepaths, recently_viewed_files = Utils.get_recent_filepaths(), diagnostics = vim.json.encode(diagnostics), history_messages = history_messages, diff --git a/lua/avante/types.lua b/lua/avante/types.lua index 49f74ac..e97a02a 100644 --- a/lua/avante/types.lua +++ b/lua/avante/types.lua @@ -314,6 +314,7 @@ vim.g.avante_login = vim.g.avante_login ---@field selected_code AvanteSelectedCode | nil ---@field project_context string | nil ---@field selected_files AvanteSelectedFile[] | nil +---@field selected_filepaths string[] | nil ---@field diagnostics string | nil ---@field history_messages AvanteLLMMessage[] | nil ---@field memory string | nil