From d10cca4265d581999c853ab6bcd4f839ba792bc3 Mon Sep 17 00:00:00 2001 From: Aaron Pham Date: Wed, 4 Sep 2024 09:15:32 -0400 Subject: [PATCH] feat(api): support for ask customization (#527) Signed-off-by: Aaron Pham --- lua/avante/api.lua | 25 +++++++++++++------ lua/avante/init.lua | 56 +++++++++++++++++++++++++++++++----------- lua/avante/sidebar.lua | 21 +++++++++------- 3 files changed, 71 insertions(+), 31 deletions(-) diff --git a/lua/avante/api.lua b/lua/avante/api.lua index f0bf364..5f89ca7 100644 --- a/lua/avante/api.lua +++ b/lua/avante/api.lua @@ -84,11 +84,21 @@ M.build = function(opts) return pid end ----@param question? string -M.ask = function(question) - if not require("avante").toggle() then return false end - if question == nil or question == "" then return true end - vim.api.nvim_exec_autocmds("User", { pattern = "AvanteInputSubmitted", data = { request = question } }) +---@class AskOptions +---@field question? string optional questions +---@field win? table windows options similar to |nvim_open_win()| + +---@param opts? AskOptions +M.ask = function(opts) + opts = opts or {} + if type(opts) == "string" then + Utils.warn("passing 'ask' as string is deprecated, do {question = '...'} instead", { once = true }) + opts = { question = opts } + end + + if not require("avante").toggle_sidebar(opts) then return false end + if opts.question == nil or opts.question == "" then return true end + vim.api.nvim_exec_autocmds("User", { pattern = "AvanteInputSubmitted", data = { request = opts.question } }) return true end @@ -108,7 +118,8 @@ M.get_suggestion = function() return suggestion end -M.refresh = function() +---@param opts? AskOptions +M.refresh = function(opts) local sidebar = require("avante").get() if not sidebar then return end if not sidebar:is_open() then return end @@ -125,7 +136,7 @@ M.refresh = function() sidebar:close() sidebar.code.winid = curwin sidebar.code.bufnr = curbuf - sidebar:render() + sidebar:render(opts) end return setmetatable(M, { diff --git a/lua/avante/init.lua b/lua/avante/init.lua index cf882b9..fb81cfe 100644 --- a/lua/avante/init.lua +++ b/lua/avante/init.lua @@ -32,11 +32,33 @@ H.commands = function() api.nvim_create_user_command("Avante" .. n, c, o) end - cmd( - "Ask", - function(opts) require("avante.api").ask(vim.trim(opts.args)) end, - { desc = "avante: ask AI for code suggestions", nargs = "*" } - ) + cmd("Ask", function(opts) + ---@type AskOptions + local args = { question = nil, win = {} } + local q_parts = {} + for _, arg in ipairs(opts.fargs) do + local value = arg:match("position=(%w+)") + if value then + args.win.position = value + else + table.insert(q_parts, arg) + end + end + args.question = #q_parts > 0 and table.concat(q_parts, " ") or nil + require("avante.api").ask(args) + end, { + desc = "avante: ask AI for code suggestions", + nargs = "*", + complete = function(_, _, _) + local candidates = {} ---@type string[] + vim.list_extend( + candidates, + ---@param x string + vim.tbl_map(function(x) return "position=" .. x end, { "left", "right", "top", "bottom" }) + ) + return candidates + end, + }) cmd("Toggle", function() M.toggle() end, { desc = "avante: toggle AI panel" }) cmd( "Edit", @@ -258,6 +280,19 @@ end M.toggle = { api = true } +---@param opts? AskOptions +M.toggle_sidebar = function(opts) + opts = opts or {} + local sidebar = M.get() + if not sidebar then + M._init(api.nvim_get_current_tabpage()) + M.current.sidebar:open(opts) + return true + end + + return sidebar:toggle(opts) +end + M.toggle.debug = H.api(Utils.toggle_wrap({ name = "debug", get = function() return Config.debug end, @@ -272,16 +307,7 @@ M.toggle.hint = H.api(Utils.toggle_wrap({ setmetatable(M.toggle, { __index = M.toggle, - __call = function() - local sidebar = M.get() - if not sidebar then - M._init(api.nvim_get_current_tabpage()) - M.current.sidebar:open() - return true - end - - return sidebar:toggle() - end, + __call = function() M.toggle_sidebar() end, }) ---@param opts? avante.Config diff --git a/lua/avante/sidebar.lua b/lua/avante/sidebar.lua index a6fecf0..eb6b301 100644 --- a/lua/avante/sidebar.lua +++ b/lua/avante/sidebar.lua @@ -66,18 +66,19 @@ function Sidebar:reset() self.input = nil end -function Sidebar:open() +---@param opts? AskOptions +function Sidebar:open(opts) local in_visual_mode = Utils.in_visual_mode() and self:in_code_win() if not self:is_open() then self:reset() self:initialize() - self:render() + self:render(opts) else if in_visual_mode then self:close() self:reset() self:initialize() - self:render() + self:render(opts) return self end self:focus() @@ -121,13 +122,14 @@ end function Sidebar:in_code_win() return self.code.winid == api.nvim_get_current_win() end -function Sidebar:toggle() +---@param opts? table +function Sidebar:toggle(opts) local in_visual_mode = Utils.in_visual_mode() and self:in_code_win() if self:is_open() and not in_visual_mode then self:close() return false else - self:open() + self:open(opts) return true end end @@ -1002,8 +1004,7 @@ local function get_chat_record_prefix(timestamp, provider, model, request) end function Sidebar:get_layout() - if Config.windows.position == "left" or Config.windows.position == "right" then return "vertical" end - return "horizontal" + return vim.tbl_contains({ "left", "right" }, Config.windows.position) and "vertical" or "horizontal" end function Sidebar:update_content_with_history(history) @@ -1478,10 +1479,12 @@ function Sidebar:get_selected_code_size() return selected_code_size end -function Sidebar:render() +---@param opts? AskOptions +function Sidebar:render(opts) + opts = opts or {} local chat_history = Path.history.load(self.code.bufnr) - local get_position = function() return Config.windows.position end + local get_position = function() return (opts and opts.win.position) and opts.win.position or Config.windows.position end local get_height = function() local selected_code_size = self:get_selected_code_size()