feat: optimize showing hints in visual mode (#2416)
This commit is contained in:
@@ -15,11 +15,13 @@ local SELECTED_CODE_NAMESPACE = api.nvim_create_namespace("avante_selected_code"
|
|||||||
local PRIORITY = (vim.hl or vim.highlight).priorities.user
|
local PRIORITY = (vim.hl or vim.highlight).priorities.user
|
||||||
|
|
||||||
---@class avante.Selection
|
---@class avante.Selection
|
||||||
|
---@field id integer
|
||||||
---@field selection avante.SelectionResult | nil
|
---@field selection avante.SelectionResult | nil
|
||||||
---@field cursor_pos table | nil
|
---@field cursor_pos table | nil
|
||||||
---@field shortcuts_extmark_id integer | nil
|
---@field shortcuts_extmark_id integer | nil
|
||||||
---@field selected_code_extmark_id integer | nil
|
---@field selected_code_extmark_id integer | nil
|
||||||
---@field augroup integer | nil
|
---@field augroup integer | nil
|
||||||
|
---@field visual_mode_augroup integer | nil
|
||||||
---@field code_winid integer | nil
|
---@field code_winid integer | nil
|
||||||
---@field code_bufnr integer | nil
|
---@field code_bufnr integer | nil
|
||||||
---@field prompt_input avante.ui.PromptInput | nil
|
---@field prompt_input avante.ui.PromptInput | nil
|
||||||
@@ -31,6 +33,7 @@ Selection.did_setup = false
|
|||||||
---@param id integer the tabpage id retrieved from api.nvim_get_current_tabpage()
|
---@param id integer the tabpage id retrieved from api.nvim_get_current_tabpage()
|
||||||
function Selection:new(id)
|
function Selection:new(id)
|
||||||
return setmetatable({
|
return setmetatable({
|
||||||
|
id = id,
|
||||||
shortcuts_extmark_id = nil,
|
shortcuts_extmark_id = nil,
|
||||||
selected_code_extmark_id = nil,
|
selected_code_extmark_id = nil,
|
||||||
augroup = api.nvim_create_augroup("avante_selection_" .. id, { clear = true }),
|
augroup = api.nvim_create_augroup("avante_selection_" .. id, { clear = true }),
|
||||||
@@ -58,12 +61,18 @@ function Selection:get_virt_text_line()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Selection:show_shortcuts_hints_popup()
|
function Selection:show_shortcuts_hints_popup()
|
||||||
self:close_shortcuts_hints_popup()
|
local virt_text_line = self:get_virt_text_line()
|
||||||
|
if self.shortcuts_extmark_id then
|
||||||
|
local extmark = vim.api.nvim_buf_get_extmark_by_id(0, NAMESPACE, self.shortcuts_extmark_id, {})
|
||||||
|
if extmark and extmark[1] == virt_text_line then
|
||||||
|
-- The hint text is already where it is supposed to be
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self:close_shortcuts_hints_popup()
|
||||||
|
end
|
||||||
|
|
||||||
local hint_text = string.format(" [%s: ask, %s: edit] ", Config.mappings.ask, Config.mappings.edit)
|
local hint_text = string.format(" [%s: ask, %s: edit] ", Config.mappings.ask, Config.mappings.edit)
|
||||||
|
|
||||||
local virt_text_line = self:get_virt_text_line()
|
|
||||||
|
|
||||||
self.shortcuts_extmark_id = api.nvim_buf_set_extmark(0, NAMESPACE, virt_text_line, -1, {
|
self.shortcuts_extmark_id = api.nvim_buf_set_extmark(0, NAMESPACE, virt_text_line, -1, {
|
||||||
virt_text = { { hint_text, "AvanteInlineHint" } },
|
virt_text = { { hint_text, "AvanteInlineHint" } },
|
||||||
virt_text_pos = "eol",
|
virt_text_pos = "eol",
|
||||||
@@ -296,8 +305,44 @@ function Selection:create_editing_input(request, line1, line2)
|
|||||||
prompt_input:open()
|
prompt_input:open()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Show the hints virtual line and set up autocommands to update it or stop showing it when exiting visual mode
|
||||||
|
---@param bufnr integer
|
||||||
|
function Selection:on_entering_visual_mode(bufnr)
|
||||||
|
if vim.bo[bufnr].buftype == "terminal" or Utils.is_sidebar_buffer(bufnr) then return end
|
||||||
|
|
||||||
|
self:show_shortcuts_hints_popup()
|
||||||
|
|
||||||
|
self.visual_mode_augroup = api.nvim_create_augroup("avante_selection_visual_" .. self.id, { clear = true })
|
||||||
|
api.nvim_create_autocmd({ "CursorMoved" }, {
|
||||||
|
group = self.visual_mode_augroup,
|
||||||
|
buffer = bufnr,
|
||||||
|
callback = function() self:show_shortcuts_hints_popup() end,
|
||||||
|
})
|
||||||
|
api.nvim_create_autocmd({ "ModeChanged" }, {
|
||||||
|
group = self.visual_mode_augroup,
|
||||||
|
buffer = bufnr,
|
||||||
|
callback = function(ev)
|
||||||
|
-- Check if exiting visual mode. Autocommand pattern matching does not work
|
||||||
|
-- with buffer-local autocommands so need to test explicitly
|
||||||
|
if ev.match:match("[vV]:[^vV]") then self:on_exiting_visual_mode() end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
api.nvim_create_autocmd({ "BufLeave" }, {
|
||||||
|
group = self.visual_mode_augroup,
|
||||||
|
buffer = bufnr,
|
||||||
|
callback = function() self:on_exiting_visual_mode() end,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
function Selection:on_exiting_visual_mode()
|
||||||
|
self:close_shortcuts_hints_popup()
|
||||||
|
|
||||||
|
api.nvim_del_augroup_by_id(self.visual_mode_augroup)
|
||||||
|
self.visual_mode_augroup = nil
|
||||||
|
end
|
||||||
|
|
||||||
function Selection:setup_autocmds()
|
function Selection:setup_autocmds()
|
||||||
Selection.did_setup = true
|
self.did_setup = true
|
||||||
|
|
||||||
api.nvim_create_autocmd("User", {
|
api.nvim_create_autocmd("User", {
|
||||||
group = self.augroup,
|
group = self.augroup,
|
||||||
@@ -308,46 +353,17 @@ function Selection:setup_autocmds()
|
|||||||
api.nvim_create_autocmd({ "ModeChanged" }, {
|
api.nvim_create_autocmd({ "ModeChanged" }, {
|
||||||
group = self.augroup,
|
group = self.augroup,
|
||||||
pattern = { "n:v", "n:V", "n:" }, -- Entering Visual mode from Normal mode
|
pattern = { "n:v", "n:V", "n:" }, -- Entering Visual mode from Normal mode
|
||||||
callback = function(ev)
|
callback = function(ev) self:on_entering_visual_mode(ev.buf) end,
|
||||||
if not Utils.is_sidebar_buffer(ev.buf) then self:show_shortcuts_hints_popup() end
|
|
||||||
end,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
api.nvim_create_autocmd({ "CursorMoved" }, {
|
|
||||||
group = self.augroup,
|
|
||||||
callback = function(ev)
|
|
||||||
if vim.bo[ev.buf].buftype ~= "terminal" and not Utils.is_sidebar_buffer(ev.buf) then
|
|
||||||
if Utils.in_visual_mode() then
|
|
||||||
self:show_shortcuts_hints_popup()
|
|
||||||
else
|
|
||||||
self:close_shortcuts_hints_popup()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
api.nvim_create_autocmd({ "ModeChanged" }, {
|
|
||||||
group = self.augroup,
|
|
||||||
pattern = { "v:n", "v:i", "v:c" }, -- Switching from visual mode back to normal, insert, or other modes
|
|
||||||
callback = function(ev)
|
|
||||||
if not Utils.is_sidebar_buffer(ev.buf) then self:close_shortcuts_hints_popup() end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
api.nvim_create_autocmd({ "BufLeave" }, {
|
|
||||||
group = self.augroup,
|
|
||||||
callback = function(ev)
|
|
||||||
if not Utils.is_sidebar_buffer(ev.buf) then self:close_shortcuts_hints_popup() end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Selection:delete_autocmds()
|
function Selection:delete_autocmds()
|
||||||
if self.augroup then api.nvim_del_augroup_by_id(self.augroup) end
|
if self.augroup then
|
||||||
self.augroup = nil
|
api.nvim_del_augroup_by_id(self.augroup)
|
||||||
Selection.did_setup = false
|
self.augroup = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
self.did_setup = false
|
||||||
end
|
end
|
||||||
|
|
||||||
return Selection
|
return Selection
|
||||||
|
|||||||
Reference in New Issue
Block a user