From 8f96d4319df662c8069ce82307d03bb1da2d0554 Mon Sep 17 00:00:00 2001 From: yetone Date: Fri, 9 May 2025 19:57:25 +0800 Subject: [PATCH] fix: relative path (#2023) --- lua/avante/file_selector.lua | 6 ++---- lua/avante/llm_tools/helpers.lua | 3 +-- lua/avante/sidebar.lua | 2 +- lua/avante/utils/file.lua | 10 ++++------ lua/avante/utils/init.lua | 18 +++++++++--------- lua/avante/utils/root.lua | 24 +++++++++++++++++++++++- 6 files changed, 40 insertions(+), 23 deletions(-) diff --git a/lua/avante/file_selector.lua b/lua/avante/file_selector.lua index a9ef06f..68c444a 100644 --- a/lua/avante/file_selector.lua +++ b/lua/avante/file_selector.lua @@ -1,5 +1,4 @@ local Utils = require("avante.utils") -local Path = require("plenary.path") local scan = require("plenary.scandir") local Config = require("avante.config") local Selector = require("avante.ui.selector") @@ -41,7 +40,7 @@ function FileSelector:handle_path_selection(selected_paths) local project_root = Utils.get_project_root() for _, selected_path in ipairs(selected_paths) do - local absolute_path = Path:new(project_root):joinpath(selected_path):absolute() + local absolute_path = Utils.join_paths(project_root, selected_path) local stat = vim.loop.fs_stat(absolute_path) if stat and stat.type == "directory" then @@ -92,8 +91,7 @@ end function FileSelector:add_selected_file(filepath) if not filepath or filepath == "" then return end - local absolute_path = filepath:sub(1, 1) == "/" and filepath - or Path:new(Utils.get_project_root()):joinpath(filepath):absolute() + local absolute_path = filepath:sub(1, 1) == "/" and filepath or Utils.join_paths(Utils.get_project_root(), filepath) local stat = vim.loop.fs_stat(absolute_path) if stat and stat.type == "directory" then diff --git a/lua/avante/llm_tools/helpers.lua b/lua/avante/llm_tools/helpers.lua index 47087cd..ef6cfe9 100644 --- a/lua/avante/llm_tools/helpers.lua +++ b/lua/avante/llm_tools/helpers.lua @@ -13,9 +13,8 @@ M.confirm_popup = nil ---@param rel_path string ---@return string function M.get_abs_path(rel_path) - if Path:new(rel_path):is_absolute() then return rel_path end local project_root = Utils.get_project_root() - local p = tostring(Path:new(project_root):joinpath(rel_path):absolute()) + local p = Utils.join_paths(project_root, rel_path) if p:sub(-2) == "/." then p = p:sub(1, -3) end return p end diff --git a/lua/avante/sidebar.lua b/lua/avante/sidebar.lua index 292bc67..a561a2f 100644 --- a/lua/avante/sidebar.lua +++ b/lua/avante/sidebar.lua @@ -1488,7 +1488,7 @@ 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 filepath = Utils.file.is_in_cwd(buf_path) and Utils.relative_path(buf_path) or buf_path + local filepath = Utils.file.is_in_project(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() diff --git a/lua/avante/utils/file.lua b/lua/avante/utils/file.lua index 8320d8c..f55d6de 100644 --- a/lua/avante/utils/file.lua +++ b/lua/avante/utils/file.lua @@ -39,13 +39,11 @@ function M.exists(filepath) return stat ~= nil end -function M.is_in_cwd(filepath) - local cwd = vim.fn.getcwd() - -- Make both paths absolute for comparison +function M.is_in_project(filepath) + local Root = require("avante.utils.root") + local project_root = Root.get() local abs_filepath = vim.fn.fnamemodify(filepath, ":p") - local abs_cwd = vim.fn.fnamemodify(cwd, ":p") - -- Check if filepath starts with cwd - return abs_filepath:sub(1, #abs_cwd) == abs_cwd + return abs_filepath:sub(1, #project_root) == project_root end function M.get_file_icon(filepath) diff --git a/lua/avante/utils/init.lua b/lua/avante/utils/init.lua index aec68c4..c9c37f0 100644 --- a/lua/avante/utils/init.lua +++ b/lua/avante/utils/init.lua @@ -580,9 +580,8 @@ function M.remove_indentation(code) end function M.relative_path(absolute) - local relative = fn.fnamemodify(absolute, ":.") - if string.sub(relative, 0, 1) == "/" then return fn.fnamemodify(absolute, ":t") end - return relative + local project_root = M.get_project_root() + return M.make_relative_path(absolute, project_root) end function M.get_doc() @@ -888,7 +887,7 @@ function M.join_paths(...) result = result .. path ::continue:: end - return result + return M.norm(result) end function M.path_exists(path) return vim.loop.fs_stat(path) ~= nil end @@ -939,9 +938,9 @@ end function M.open_buffer(path, set_current_buf) if set_current_buf == nil then set_current_buf = true end - path = vim.fn.fnamemodify(path, ":p") + local abs_path = M.join_paths(M.get_project_root(), path) - local bufnr = vim.fn.bufnr(path, true) + local bufnr = vim.fn.bufnr(abs_path, true) vim.fn.bufload(bufnr) if set_current_buf then vim.api.nvim_set_current_buf(bufnr) end @@ -1043,7 +1042,7 @@ end function M.uniform_path(path) if type(path) ~= "string" then path = tostring(path) end - if not M.file.is_in_cwd(path) then return path end + if not M.file.is_in_project(path) then return path end local project_root = M.get_project_root() local abs_path = M.is_absolute_path(path) and path or M.join_paths(project_root, path) local relative_path = M.make_relative_path(abs_path, project_root) @@ -1070,8 +1069,9 @@ end ---@return string[]|nil lines ---@return string|nil error function M.read_file_from_buf_or_disk(filepath) + local abs_path = M.join_paths(M.get_project_root(), filepath) --- Lookup if the file is loaded in a buffer - local bufnr = vim.fn.bufnr(filepath) + local bufnr = vim.fn.bufnr(abs_path) 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) @@ -1079,7 +1079,7 @@ function M.read_file_from_buf_or_disk(filepath) end -- Fallback: read file from disk - local file, open_err = io.open(filepath, "r") + local file, open_err = io.open(abs_path, "r") if file then local content = file:read("*all") file:close() diff --git a/lua/avante/utils/root.lua b/lua/avante/utils/root.lua index 5f62f46..885cb8a 100644 --- a/lua/avante/utils/root.lua +++ b/lua/avante/utils/root.lua @@ -56,7 +56,29 @@ function M.detectors.pattern(buf, patterns) return pattern and { vim.fs.dirname(pattern) } or {} end -function M.bufpath(buf) return M.realpath(vim.api.nvim_buf_get_name(assert(buf))) end +function M.bufpath(buf) + if buf == nil or type(buf) ~= "number" then + -- TODO: Consider logging this unexpected buffer type or nil value if assert was bypassed. + vim.notify("avante: M.bufpath received invalid buffer: " .. tostring(buf), vim.log.levels.WARN) + return nil + end + + local buf_name_str + local success, result = pcall(vim.api.nvim_buf_get_name, buf) + + if not success then + -- TODO: Consider logging the actual error from pcall. + vim.notify( + "avante: nvim_buf_get_name failed for buffer " .. tostring(buf) .. ": " .. tostring(result), + vim.log.levels.WARN + ) + return nil + end + buf_name_str = result + + -- M.realpath will handle buf_name_str == "" (empty string for unnamed buffer) correctly, returning nil. + return M.realpath(buf_name_str) +end function M.cwd() return M.realpath(vim.uv.cwd()) or "" end