fix: slow typing in input window and other input hint optimizations (#2418)
This commit is contained in:
@@ -245,6 +245,7 @@ function M.select_history()
|
||||
local sidebar = require("avante").get()
|
||||
sidebar:update_content_with_history()
|
||||
sidebar:create_todos_container()
|
||||
sidebar:initialize_token_count()
|
||||
vim.schedule(function() sidebar:focus_input() end)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -66,6 +66,7 @@ Sidebar.__index = Sidebar
|
||||
---@field input_hint_window integer | nil
|
||||
---@field ask_opts AskOptions
|
||||
---@field old_result_lines avante.ui.Line[]
|
||||
---@field token_count integer | nil
|
||||
|
||||
---@param id integer the tabpage id retrieved from api.nvim_get_current_tabpage()
|
||||
function Sidebar:new(id)
|
||||
@@ -97,7 +98,8 @@ function Sidebar:new(id)
|
||||
input_hint_window = nil,
|
||||
ask_opts = {},
|
||||
old_result_lines = {},
|
||||
-- 缓存相关字段
|
||||
token_count = nil,
|
||||
-- Cache-related fields
|
||||
_cached_history_lines = nil,
|
||||
_history_cache_invalidated = true,
|
||||
}, Sidebar)
|
||||
@@ -137,6 +139,7 @@ function Sidebar:reset()
|
||||
self.input_container = nil
|
||||
self.scroll = true
|
||||
self.old_result_lines = {}
|
||||
self.token_count = nil
|
||||
end
|
||||
|
||||
---@class SidebarOpenOptions: AskOptions
|
||||
@@ -259,7 +262,10 @@ function Sidebar:focus()
|
||||
end
|
||||
|
||||
function Sidebar:focus_input()
|
||||
if Utils.is_valid_container(self.input_container, true) then api.nvim_set_current_win(self.input_container.winid) end
|
||||
if Utils.is_valid_container(self.input_container, true) then
|
||||
api.nvim_set_current_win(self.input_container.winid)
|
||||
self:show_input_hint()
|
||||
end
|
||||
end
|
||||
|
||||
function Sidebar:is_open() return Utils.is_valid_container(self.result_container, true) end
|
||||
@@ -2171,44 +2177,34 @@ function Sidebar:show_input_hint()
|
||||
self:close_input_hint() -- Close the existing hint window
|
||||
|
||||
local hint_text = (fn.mode() ~= "i" and Config.mappings.submit.normal or Config.mappings.submit.insert) .. ": submit"
|
||||
|
||||
local function show()
|
||||
local buf = api.nvim_create_buf(false, true)
|
||||
api.nvim_buf_set_lines(buf, 0, -1, false, { hint_text })
|
||||
api.nvim_buf_set_extmark(buf, INPUT_HINT_NAMESPACE, 0, 0, { hl_group = "AvantePopupHint", end_col = #hint_text })
|
||||
|
||||
-- Get the current window size
|
||||
local win_width = api.nvim_win_get_width(self.input_container.winid)
|
||||
local width = #hint_text
|
||||
|
||||
-- Set the floating window options
|
||||
local win_opts = {
|
||||
relative = "win",
|
||||
win = self.input_container.winid,
|
||||
width = width,
|
||||
height = 1,
|
||||
row = self:get_input_float_window_row(),
|
||||
col = math.max(win_width - width, 0), -- Display in the bottom right corner
|
||||
style = "minimal",
|
||||
border = "none",
|
||||
focusable = false,
|
||||
zindex = 100,
|
||||
}
|
||||
|
||||
-- Create the floating window
|
||||
self.input_hint_window = api.nvim_open_win(buf, false, win_opts)
|
||||
end
|
||||
|
||||
if Config.behaviour.enable_token_counting then
|
||||
local input_value = table.concat(api.nvim_buf_get_lines(self.input_container.bufnr, 0, -1, false), "\n")
|
||||
self:get_generate_prompts_options(input_value, function(generate_prompts_options)
|
||||
local tokens = Llm.calculate_tokens(generate_prompts_options) + Utils.tokens.calculate_tokens(input_value)
|
||||
hint_text = "Tokens: " .. tostring(tokens) .. "; " .. hint_text
|
||||
show()
|
||||
end)
|
||||
else
|
||||
show()
|
||||
if self.token_count == nil then self:initialize_token_count() end
|
||||
local tokens = self.token_count + Utils.tokens.calculate_tokens(input_value)
|
||||
hint_text = "Tokens: " .. tostring(tokens) .. "; " .. hint_text
|
||||
end
|
||||
|
||||
local buf = api.nvim_create_buf(false, true)
|
||||
api.nvim_buf_set_lines(buf, 0, -1, false, { hint_text })
|
||||
api.nvim_buf_set_extmark(buf, INPUT_HINT_NAMESPACE, 0, 0, { hl_group = "AvantePopupHint", end_col = #hint_text })
|
||||
|
||||
-- Get the current window size
|
||||
local win_width = api.nvim_win_get_width(self.input_container.winid)
|
||||
local width = #hint_text
|
||||
|
||||
-- Create the floating window
|
||||
self.input_hint_window = api.nvim_open_win(buf, false, {
|
||||
relative = "win",
|
||||
win = self.input_container.winid,
|
||||
width = width,
|
||||
height = 1,
|
||||
row = self:get_input_float_window_row(),
|
||||
col = math.max(win_width - width, 0), -- Display in the bottom right corner
|
||||
style = "minimal",
|
||||
border = "none",
|
||||
focusable = false,
|
||||
zindex = 100,
|
||||
})
|
||||
end
|
||||
|
||||
function Sidebar:close_selected_files_hint()
|
||||
@@ -2248,6 +2244,7 @@ function Sidebar:show_selected_files_hint()
|
||||
end
|
||||
|
||||
function Sidebar:reload_chat_history()
|
||||
self.token_count = nil
|
||||
if not self.code.bufnr or not api.nvim_buf_is_valid(self.code.bufnr) then return end
|
||||
self.chat_history = Path.history.load(self.code.bufnr)
|
||||
self._history_cache_invalidated = true
|
||||
@@ -2541,7 +2538,7 @@ function Sidebar:get_history_messages_for_api(opts)
|
||||
end
|
||||
|
||||
---@param request string
|
||||
---@param cb fun(opts: AvanteGeneratePromptsOptions): nil
|
||||
---@param cb? fun(opts: AvanteGeneratePromptsOptions): nil
|
||||
function Sidebar:get_generate_prompts_options(request, cb)
|
||||
local filetype = api.nvim_get_option_value("filetype", { buf = self.code.bufnr })
|
||||
local file_ext = nil
|
||||
@@ -2634,7 +2631,13 @@ function Sidebar:get_generate_prompts_options(request, cb)
|
||||
|
||||
if self.chat_history.memory then prompts_opts.memory = self.chat_history.memory.content end
|
||||
|
||||
cb(prompts_opts)
|
||||
if Config.behaviour.enable_token_counting then self.token_count = Llm.calculate_tokens(prompts_opts) end
|
||||
|
||||
if cb then cb(prompts_opts) end
|
||||
end
|
||||
|
||||
function Sidebar:initialize_token_count()
|
||||
if Config.behaviour.enable_token_counting then self:get_generate_prompts_options("") end
|
||||
end
|
||||
|
||||
function Sidebar:create_input_container()
|
||||
@@ -2968,11 +2971,14 @@ function Sidebar:create_input_container()
|
||||
callback = function() end,
|
||||
})
|
||||
|
||||
local debounced_show_input_hint = Utils.debounce(function()
|
||||
if vim.api.nvim_win_is_valid(self.input_container.winid) then self:show_input_hint() end
|
||||
end, 200)
|
||||
api.nvim_create_autocmd({ "TextChanged", "TextChangedI", "VimResized" }, {
|
||||
group = self.augroup,
|
||||
buffer = self.input_container.bufnr,
|
||||
callback = function()
|
||||
self:show_input_hint()
|
||||
debounced_show_input_hint()
|
||||
place_sign_at_first_line(self.input_container.bufnr)
|
||||
end,
|
||||
})
|
||||
@@ -2985,10 +2991,8 @@ function Sidebar:create_input_container()
|
||||
|
||||
api.nvim_create_autocmd("WinClosed", {
|
||||
group = self.augroup,
|
||||
callback = function(args)
|
||||
local closed_winid = tonumber(args.match)
|
||||
if closed_winid == self.input_container.winid then self:close_input_hint() end
|
||||
end,
|
||||
pattern = tostring(self.input_container.winid),
|
||||
callback = function() self:close_input_hint() end,
|
||||
})
|
||||
|
||||
api.nvim_create_autocmd("BufEnter", {
|
||||
@@ -3002,27 +3006,17 @@ function Sidebar:create_input_container()
|
||||
api.nvim_create_autocmd("BufLeave", {
|
||||
group = self.augroup,
|
||||
buffer = self.input_container.bufnr,
|
||||
callback = function() vim.cmd("noautocmd stopinsert") end,
|
||||
})
|
||||
|
||||
-- Show hint in insert mode
|
||||
api.nvim_create_autocmd("ModeChanged", {
|
||||
group = self.augroup,
|
||||
pattern = "*:i",
|
||||
callback = function()
|
||||
local cur_buf = api.nvim_get_current_buf()
|
||||
if self.input_container and cur_buf == self.input_container.bufnr then self:show_input_hint() end
|
||||
vim.cmd("noautocmd stopinsert")
|
||||
self:close_input_hint()
|
||||
end,
|
||||
})
|
||||
|
||||
-- Close hint when exiting insert mode
|
||||
-- Update hint on mode change as submit key sequence may be different
|
||||
api.nvim_create_autocmd("ModeChanged", {
|
||||
group = self.augroup,
|
||||
pattern = "i:*",
|
||||
callback = function()
|
||||
local cur_buf = api.nvim_get_current_buf()
|
||||
if self.input_container and cur_buf == self.input_container.bufnr then self:show_input_hint() end
|
||||
end,
|
||||
buffer = self.input_container.bufnr,
|
||||
callback = function() self:show_input_hint() end,
|
||||
})
|
||||
|
||||
api.nvim_create_autocmd("WinEnter", {
|
||||
@@ -3045,9 +3039,6 @@ function Sidebar:create_input_container()
|
||||
end,
|
||||
})
|
||||
|
||||
-- Clear hint when leaving the window
|
||||
self.input_container:on(event.BufLeave, function() self:close_input_hint() end, {})
|
||||
|
||||
self:refresh_winids()
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user