From a6b24f338746b2bae49452a4aed2c7255cc1f2df Mon Sep 17 00:00:00 2001 From: yetone Date: Thu, 20 Feb 2025 16:02:52 +0800 Subject: [PATCH] fix: use the current filepath when the filepath of code block cannot be found (#1319) --- lua/avante/file_selector.lua | 8 ++++---- lua/avante/sidebar.lua | 37 +++++++++++++++++++++++++++--------- lua/avante/utils/init.lua | 9 ++++----- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/lua/avante/file_selector.lua b/lua/avante/file_selector.lua index 44eb3e8..015b52d 100644 --- a/lua/avante/file_selector.lua +++ b/lua/avante/file_selector.lua @@ -378,15 +378,15 @@ end ---@return { path: string, content: string, file_type: string }[] function FileSelector:get_selected_files_contents() local contents = {} - for _, file_path in ipairs(self.selected_filepaths) do - local lines, error = Utils.read_file_from_buf_or_disk(file_path) + for _, filepath in ipairs(self.selected_filepaths) do + local lines, error = Utils.read_file_from_buf_or_disk(filepath) lines = lines or {} - local filetype = Utils.get_filetype(file_path) + 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(contents, { path = file_path, content = content, file_type = filetype }) + table.insert(contents, { path = filepath, content = content, file_type = filetype }) end end return contents diff --git a/lua/avante/sidebar.lua b/lua/avante/sidebar.lua index 236c65e..47e3cda 100644 --- a/lua/avante/sidebar.lua +++ b/lua/avante/sidebar.lua @@ -523,7 +523,7 @@ end --- ---@param response_content string ---@return table -local function extract_cursor_planning_code_snippets_map(response_content) +local function extract_cursor_planning_code_snippets_map(response_content, current_filepath, current_filetype) local snippets = {} local current_snippet = {} local in_code_block = false @@ -540,8 +540,18 @@ local function extract_cursor_planning_code_snippets_map(response_content) if in_code_block then in_code_block = false if filepath == nil or filepath == "" then - Utils.warn("Failed to parse filepath from code block") - goto continue + if lang == current_filetype then + filepath = current_filepath + else + Utils.warn( + string.format( + "Failed to parse filepath from code block, and current_filetype `%s` is not the same as the filetype `%s` of the current code block, so ignore this code block", + current_filetype, + lang + ) + ) + goto continue + end end table.insert(snippets, { range = { 0, 0 }, @@ -762,7 +772,7 @@ end ---@param buf integer ---@return AvanteCodeblock[] -local function parse_codeblocks(buf) +local function parse_codeblocks(buf, current_filepath, current_filetype) local codeblocks = {} local in_codeblock = false local start_line = nil @@ -782,6 +792,7 @@ local function parse_codeblocks(buf) if not filepath then if lines[i + 1] then filepath = lines[i + 1]:match("[Ff][Ii][Ll][Ee][Pp][Aa][Tt][Hh]:%s*(.*)$") end end + if not filepath and lang_ == current_filetype then filepath = current_filepath end if filepath then lang = lang_ start_line = i - 1 @@ -862,9 +873,13 @@ end ---@param current_cursor boolean function Sidebar:apply(current_cursor) + local buf_path = api.nvim_buf_get_name(self.code.bufnr) + local current_filepath = Utils.file.is_in_cwd(buf_path) and Utils.relative_path(buf_path) or buf_path + local current_filetype = Utils.get_filetype(current_filepath) + local response, response_start_line = self:get_content_between_separators() local all_snippets_map = Config.behaviour.enable_cursor_planning_mode - and extract_cursor_planning_code_snippets_map(response) + and extract_cursor_planning_code_snippets_map(response, current_filepath, current_filetype) or extract_code_snippets_map(response) if not Config.behaviour.enable_cursor_planning_mode then all_snippets_map = ensure_snippets_no_overlap(all_snippets_map) @@ -1515,10 +1530,14 @@ function Sidebar:on_mount(opts) end, }) + local buf_path = api.nvim_buf_get_name(self.code.bufnr) + local current_filepath = Utils.file.is_in_cwd(buf_path) and Utils.relative_path(buf_path) or buf_path + local current_filetype = Utils.get_filetype(current_filepath) + api.nvim_create_autocmd({ "BufEnter", "BufWritePost" }, { buffer = self.result_container.bufnr, callback = function(ev) - codeblocks = parse_codeblocks(ev.buf) + codeblocks = parse_codeblocks(ev.buf, current_filepath, current_filetype) self:bind_sidebar_keys(codeblocks) end, }) @@ -1533,7 +1552,7 @@ function Sidebar:on_mount(opts) then return end - codeblocks = parse_codeblocks(self.result_container.bufnr) + codeblocks = parse_codeblocks(self.result_container.bufnr, current_filepath, current_filetype) self:bind_sidebar_keys(codeblocks) end, }) @@ -1680,11 +1699,11 @@ function Sidebar:initialize() local buf_path = api.nvim_buf_get_name(self.code.bufnr) -- if the filepath is outside of the current working directory then we want the absolute path - local file_path = Utils.file.is_in_cwd(buf_path) and Utils.relative_path(buf_path) or buf_path + local filepath = Utils.file.is_in_cwd(buf_path) and Utils.relative_path(buf_path) or buf_path Utils.debug("Sidebar:initialize adding buffer to file selector", buf_path) self.file_selector:reset() - self.file_selector:add_selected_file(file_path) + self.file_selector:add_selected_file(filepath) return self end diff --git a/lua/avante/utils/init.lua b/lua/avante/utils/init.lua index fef7648..14626ee 100644 --- a/lua/avante/utils/init.lua +++ b/lua/avante/utils/init.lua @@ -914,12 +914,12 @@ function M.get_filetype(filepath) return filetype end ----@param file_path string +---@param filepath string ---@return string[]|nil lines ---@return string|nil error -function M.read_file_from_buf_or_disk(file_path) +function M.read_file_from_buf_or_disk(filepath) --- Lookup if the file is loaded in a buffer - local bufnr = vim.fn.bufnr(file_path) + local bufnr = vim.fn.bufnr(filepath) if bufnr ~= -1 and vim.api.nvim_buf_is_loaded(bufnr) then -- If buffer exists and is loaded, get buffer content local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) @@ -927,13 +927,12 @@ function M.read_file_from_buf_or_disk(file_path) end -- Fallback: read file from disk - local file, open_err = io.open(file_path, "r") + local file, open_err = io.open(filepath, "r") if file then local content = file:read("*all") file:close() return vim.split(content, "\n"), nil else - -- M.error("failed to open file: " .. file_path .. " with error: " .. open_err) return {}, open_err end end