diff --git a/README.md b/README.md index 3585033..78c676b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ ### [Warp, the intelligent terminal for developers](https://www.warp.dev/avantenvim) + [Available for MacOS, Linux, & Windows](https://www.warp.dev/avantenvim)
@@ -954,6 +955,43 @@ If you have the following structure: > > `*.avanterules` is a jinja template file, in which will be rendered using [minijinja](https://github.com/mitsuhiko/minijinja). See [templates](https://github.com/yetone/avante.nvim/blob/main/lua/avante/templates) for example on how to extend current templates. +## Integration + +Avante.nvim can be extended to work with other plugins by using its extension modules. Below is an example of integrating Avante with [`nvim-tree`](https://github.com/nvim-tree/nvim-tree.lua), allowing you to select or deselect files directly from the NvimTree UI: + +```lua +{ + "yetone/avante.nvim", + event = "VeryLazy", + keys = { + { + "a+", + function() + local tree_ext = require("avante.extensions.nvim_tree") + tree_ext.add_file() + end, + desc = "Select file in NvimTree", + ft = "NvimTree", + }, + { + "a-", + function() + local tree_ext = require("avante.extensions.nvim_tree") + tree_ext.remove_file() + end, + desc = "Deselect file in NvimTree", + ft = "NvimTree", + }, + }, + opts = { + --- other configurations + selector = { + exclude_auto_select = { "NvimTree" }, + }, + }, +} +``` + ## TODOs - [x] Chat with current file diff --git a/README_zh.md b/README_zh.md index 5b133f9..f3bd4c6 100644 --- a/README_zh.md +++ b/README_zh.md @@ -951,6 +951,43 @@ vim.keymap.set("n", "am", function() vim.api.nvim_exec_autocmds("User", > > `*.avanterules` 是一个 jinja 模板文件,将使用 [minijinja](https://github.com/mitsuhiko/minijinja) 渲染。有关如何扩展当前模板的示例,请参见 [templates](https://github.com/yetone/avante.nvim/blob/main/lua/avante/templates)。 +## 集成 + +Avante.nvim 可以通过其扩展模块与其他插件协同工作。下面是一个将 Avante 与 nvim-tree 集成的示例,允许你直接从 NvimTree UI 中选择或取消选择文件: + +```lua +{ + "yetone/avante.nvim", + event = "VeryLazy", + keys = { + { + "a+", + function() + local tree_ext = require("avante.extensions.nvim_tree") + tree_ext.add_file() + end, + desc = "Select file in NvimTree", + ft = "NvimTree", + }, + { + "a-", + function() + local tree_ext = require("avante.extensions.nvim_tree") + tree_ext.remove_file() + end, + desc = "Deselect file in NvimTree", + ft = "NvimTree", + }, + }, + opts = { + --- 其他配置 + selector = { + exclude_auto_select = { "NvimTree" }, + }, + }, +} +``` + ## TODOs - [x] 与当前文件聊天 diff --git a/lua/avante/api.lua b/lua/avante/api.lua index 6711668..d1f11b0 100644 --- a/lua/avante/api.lua +++ b/lua/avante/api.lua @@ -249,6 +249,42 @@ function M.add_buffer_files() sidebar.file_selector:add_buffer_files() end +function M.add_selected_file(filepath) + local rel_path = Utils.uniform_path(filepath) + + local sidebar = require("avante").get() + if not sidebar then + require("avante.api").ask() + sidebar = require("avante").get() + end + if not sidebar:is_open() then sidebar:open({}) end + sidebar.file_selector:add_selected_file(rel_path) +end + +function M.remove_selected_file(filepath) + ---@diagnostic disable-next-line: undefined-field + local stat = vim.loop.fs_stat(filepath) + local files + if stat and stat.type == "directory" then + files = Utils.scan_directory({ directory = filepath, add_dirs = true }) + else + files = { filepath } + end + + local sidebar = require("avante").get() + if not sidebar then + require("avante.api").ask() + sidebar = require("avante").get() + end + if not sidebar:is_open() then sidebar:open({}) end + + for _, file in ipairs(files) do + local rel_path = Utils.uniform_path(file) + vim.notify(rel_path) + sidebar.file_selector:remove_selected_file(rel_path) + end +end + function M.stop() require("avante.llm").cancel_inflight_request() end return setmetatable(M, { diff --git a/lua/avante/extensions/init.lua b/lua/avante/extensions/init.lua new file mode 100644 index 0000000..198faaa --- /dev/null +++ b/lua/avante/extensions/init.lua @@ -0,0 +1,10 @@ +---@class avante.extensions +local M = {} + +setmetatable(M, { + __index = function(t, k) + ---@diagnostic disable-next-line: no-unknown + t[k] = require("avante.extensions." .. k) + return t[k] + end, +}) diff --git a/lua/avante/extensions/nvim_tree.lua b/lua/avante/extensions/nvim_tree.lua new file mode 100644 index 0000000..c3b3dc2 --- /dev/null +++ b/lua/avante/extensions/nvim_tree.lua @@ -0,0 +1,56 @@ +local Api = require("avante.api") + +--- @class avante.extensions.nvim_tree +local M = {} + +--- Adds the currently selected file in NvimTree to the selection via Api.add_selected_file. +-- Notifies the user if not invoked within NvimTree or if errors occur. +--- @return nil +function M.add_file() + if vim.bo.filetype ~= "NvimTree" then + vim.notify("This action can only be used inside NvimTree.", vim.log.levels.WARN) + return + end + + local ok, nvim_tree_api = pcall(require, "nvim-tree.api") + if not ok then + vim.notify("nvim-tree needed", vim.log.levels.ERROR) + return + end + + local success, node = pcall(function() return nvim_tree_api.tree.get_node_under_cursor() end) + if not success then + vim.notify("Error getting node: " .. tostring(node), vim.log.levels.ERROR) + return + end + + local filepath = node.absolute_path + Api.add_selected_file(filepath) +end + +--- Removes the currently selected file in NvimTree from the selection via Api.remove_selected_file. +-- Notifies the user if not invoked within NvimTree or if errors occur. +--- @return nil +function M.remove_file() + if vim.bo.filetype ~= "NvimTree" then + vim.notify("This action can only be used inside NvimTree.", vim.log.levels.WARN) + return + end + + local ok, nvim_tree_api = pcall(require, "nvim-tree.api") + if not ok then + vim.notify("nvim-tree needed", vim.log.levels.ERROR) + return + end + + local success, node = pcall(function() return nvim_tree_api.tree.get_node_under_cursor() end) + if not success then + vim.notify("Error getting node: " .. tostring(node), vim.log.levels.ERROR) + return + end + + local filepath = node.absolute_path + Api.remove_selected_file(filepath) +end + +return M