From 29e109e447e30854234a94365114ccd619e92ed4 Mon Sep 17 00:00:00 2001 From: Aaron Pham Date: Thu, 5 Sep 2024 02:43:31 -0400 Subject: [PATCH] feat(api): support native chat mode (#541) Signed-off-by: Aaron Pham --- autoload/avante.vim | 2 +- lua/avante/api.lua | 5 +++-- lua/avante/init.lua | 18 +++++++++++++++--- lua/avante/llm.lua | 3 ++- lua/avante/selection.lua | 1 + lua/avante/sidebar.lua | 38 ++++++++++++++++++++++---------------- lua/avante/suggestion.lua | 1 + 7 files changed, 45 insertions(+), 23 deletions(-) diff --git a/autoload/avante.vim b/autoload/avante.vim index 6006e98..4a8ee49 100644 --- a/autoload/avante.vim +++ b/autoload/avante.vim @@ -1,4 +1,4 @@ function avante#build(...) abort let l:source = get(a:, 1, v:false) - return join(luaeval("require('avante').build(_A)", l:source), "\n") + return join(luaeval("require('avante_lib').load()"),"\n",luaeval("require('avante.api').build(_A)", l:source), "\n") endfunction diff --git a/lua/avante/api.lua b/lua/avante/api.lua index 5f89ca7..bd010fc 100644 --- a/lua/avante/api.lua +++ b/lua/avante/api.lua @@ -73,9 +73,9 @@ M.build = function(opts) local output = stdout if #output == 0 then table.insert(output, "") - Utils.info("outputs: " .. output) + Utils.debug(output) else - Utils.error("error: " .. stderr) + Utils.debug(stderr) end end end) @@ -87,6 +87,7 @@ end ---@class AskOptions ---@field question? string optional questions ---@field win? table windows options similar to |nvim_open_win()| +---@field ask? boolean ---@param opts? AskOptions M.ask = function(opts) diff --git a/lua/avante/init.lua b/lua/avante/init.lua index fb81cfe..fe7c4e9 100644 --- a/lua/avante/init.lua +++ b/lua/avante/init.lua @@ -36,16 +36,25 @@ H.commands = function() ---@type AskOptions local args = { question = nil, win = {} } local q_parts = {} + local q_ask = nil for _, arg in ipairs(opts.fargs) do local value = arg:match("position=(%w+)") - if value then + local ask = arg:match("ask=(%w+)") + if ask ~= nil then + q_ask = ask == "true" + elseif 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) + require("avante.api").ask( + vim.tbl_deep_extend( + "force", + args, + { ask = q_ask, question = #q_parts > 0 and table.concat(q_parts, " ") or nil } + ) + ) end, { desc = "avante: ask AI for code suggestions", nargs = "*", @@ -56,6 +65,7 @@ H.commands = function() ---@param x string vim.tbl_map(function(x) return "position=" .. x end, { "left", "right", "top", "bottom" }) ) + vim.list_extend(candidates, vim.tbl_map(function(x) return "ask=" .. x end, { "true", "false" })) return candidates end, }) @@ -283,6 +293,8 @@ M.toggle = { api = true } ---@param opts? AskOptions M.toggle_sidebar = function(opts) opts = opts or {} + if opts.ask == nil then opts.ask = true end + local sidebar = M.get() if not sidebar then M._init(api.nvim_get_current_tabpage()) diff --git a/lua/avante/llm.lua b/lua/avante/llm.lua index 21e7a62..99bc70b 100644 --- a/lua/avante/llm.lua +++ b/lua/avante/llm.lua @@ -29,6 +29,7 @@ local group = api.nvim_create_augroup("avante_llm", { clear = true }) ---@field memory_context string | nil --- ---@class StreamOptions: TemplateOptions +---@field ask boolean ---@field bufnr integer ---@field instructions string ---@field mode LlmMode @@ -60,7 +61,7 @@ M.stream = function(opts) local template_opts = { use_xml_format = Provider.use_xml_format, - ask = true, -- TODO: add mode without ask instruction + ask = opts.ask, -- TODO: add mode without ask instruction question = original_instructions, code_lang = opts.code_lang, file_content = opts.file_content, diff --git a/lua/avante/selection.lua b/lua/avante/selection.lua index 3142d99..272cad3 100644 --- a/lua/avante/selection.lua +++ b/lua/avante/selection.lua @@ -395,6 +395,7 @@ function Selection:create_editing_input() Llm.stream({ bufnr = code_bufnr, + ask = true, file_content = code_content, code_lang = filetype, selected_code = self.selection.content, diff --git a/lua/avante/sidebar.lua b/lua/avante/sidebar.lua index 005b4a6..a47c223 100644 --- a/lua/avante/sidebar.lua +++ b/lua/avante/sidebar.lua @@ -66,7 +66,7 @@ function Sidebar:reset() self.input = nil end ----@param opts? AskOptions +---@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 @@ -122,7 +122,7 @@ end function Sidebar:in_code_win() return self.code.winid == api.nvim_get_current_win() end ----@param opts? table +---@param opts AskOptions 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 @@ -592,7 +592,9 @@ function Sidebar:render_result() self:render_header(self.result.winid, self.result.bufnr, header_text, Highlights.TITLE, Highlights.REVERSED_TITLE) end -function Sidebar:render_input() +---@param ask? boolean +function Sidebar:render_input(ask) + if ask == nil then ask = true end if not self.input or not self.input.bufnr or not api.nvim_buf_is_valid(self.input.bufnr) then return end local filetype = api.nvim_get_option_value("filetype", { buf = self.code.bufnr }) @@ -614,11 +616,13 @@ function Sidebar:render_input() local code_file_fullpath = api.nvim_buf_get_name(self.code.bufnr) local code_filename = fn.fnamemodify(code_file_fullpath, ":t") - local header_text = string.format("󱜸 Chat with %s %s (: switch focus)", icon, code_filename) + local header_text = + string.format("󱜸 %s %s %s (: switch focus)", ask and "Ask" or "Chat with", icon, code_filename) if self.code.selection ~= nil then header_text = string.format( - "󱜸 Chat with %s %s(%d:%d) (: switch focus)", + "󱜸 %s %s %s(%d:%d) (: switch focus)", + ask and "Ask" or "Chat with", icon, code_filename, self.code.selection.range.start.line, @@ -664,7 +668,8 @@ function Sidebar:render_selected_code() ) end -function Sidebar:on_mount() +---@param opts AskOptions +function Sidebar:on_mount(opts) self:refresh_winids() api.nvim_set_option_value("wrap", Config.windows.wrap, { win = self.result.winid }) @@ -795,7 +800,7 @@ function Sidebar:on_mount() }) self:render_result() - self:render_input() + self:render_input(opts.ask) self:render_selected_code() self.augroup = api.nvim_create_augroup("avante_sidebar_" .. self.id .. self.result.winid, { clear = true }) @@ -1148,7 +1153,8 @@ end local hint_window = nil -function Sidebar:create_input() +---@param opts AskOptions +function Sidebar:create_input(opts) if self.input then self.input:unmount() end if not self.code.bufnr or not api.nvim_buf_is_valid(self.code.bufnr) then return end @@ -1266,6 +1272,7 @@ function Sidebar:create_input() Llm.stream({ bufnr = self.code.bufnr, + ask = opts.ask, file_content = content_with_line_numbers, code_lang = filetype, selected_code = selected_code_content_with_line_numbers, @@ -1396,7 +1403,7 @@ function Sidebar:create_input() local width = #hint_text -- Set the floating window options - local opts = { + local win_opts = { relative = "win", win = self.input.winid, width = width, @@ -1410,7 +1417,7 @@ function Sidebar:create_input() } -- Create the floating window - hint_window = api.nvim_open_win(buf, false, opts) + hint_window = api.nvim_open_win(buf, false, win_opts) api.nvim_win_set_hl_ns(hint_window, Highlights.hint_ns) end @@ -1461,14 +1468,14 @@ function Sidebar:create_input() end, }) - self:refresh_winids() - api.nvim_create_autocmd("User", { pattern = "AvanteInputSubmitted", callback = function(ev) if ev.data and ev.data.request then handle_submit(ev.data.request) end end, }) + + self:refresh_winids() end function Sidebar:get_selected_code_size() @@ -1485,9 +1492,8 @@ function Sidebar:get_selected_code_size() return selected_code_size end ----@param opts? AskOptions +---@param opts AskOptions function Sidebar:render(opts) - opts = opts or {} local chat_history = Path.history.load(self.code.bufnr) local get_position = function() @@ -1546,7 +1552,7 @@ function Sidebar:render(opts) self:close() end) - self:create_input() + self:create_input(opts) self:update_content_with_history(chat_history) @@ -1557,7 +1563,7 @@ function Sidebar:render(opts) self:create_selected_code() - self:on_mount() + self:on_mount(opts) return self end diff --git a/lua/avante/suggestion.lua b/lua/avante/suggestion.lua index e01f8b3..4cd063f 100644 --- a/lua/avante/suggestion.lua +++ b/lua/avante/suggestion.lua @@ -107,6 +107,7 @@ function Suggestion:suggest() Llm.stream({ bufnr = bufnr, + ask = true, file_content = code_content, code_lang = filetype, instructions = vim.json.encode(doc),