feat(api): support native chat mode (#541)

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>
This commit is contained in:
Aaron Pham 2024-09-05 02:43:31 -04:00 committed by GitHub
parent a8ef7de7d8
commit 29e109e447
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 45 additions and 23 deletions

View File

@ -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

View File

@ -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<string, any> windows options similar to |nvim_open_win()|
---@field ask? boolean
---@param opts? AskOptions
M.ask = function(opts)

View File

@ -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())

View File

@ -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,

View File

@ -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,

View File

@ -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<string, any>
---@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 (<Tab>: switch focus)", icon, code_filename)
local header_text =
string.format("󱜸 %s %s %s (<Tab>: 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) (<Tab>: switch focus)",
"󱜸 %s %s %s(%d:%d) (<Tab>: 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

View File

@ -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),