feat(mapping): plug and expose API (#346)
Signed-off-by: Aaron Pham <contact@aarnphm.xyz>
This commit is contained in:
parent
8a683b053b
commit
2e6a26240e
17
README.md
17
README.md
@ -26,6 +26,11 @@ Install `avante.nvim` using [lazy.nvim](https://github.com/folke/lazy.nvim):
|
|||||||
opts = {
|
opts = {
|
||||||
-- add any opts here
|
-- add any opts here
|
||||||
},
|
},
|
||||||
|
keys = { -- See https://github.com/yetone/avante.nvim/wiki#keymaps for more info
|
||||||
|
{ "<leader>aa", function() require("avante.api").ask() end, desc = "avante: ask", mode = { "n", "v" } },
|
||||||
|
{ "<leader>ar", function() require("avante.api").refresh() end, desc = "avante: refresh", mode = "v" },
|
||||||
|
{ "<leader>ae", function() require("avante.api").edit() end, desc = "avante: edit", mode = { "n", "v" } },
|
||||||
|
},
|
||||||
dependencies = {
|
dependencies = {
|
||||||
"stevearc/dressing.nvim",
|
"stevearc/dressing.nvim",
|
||||||
"nvim-lua/plenary.nvim",
|
"nvim-lua/plenary.nvim",
|
||||||
@ -94,9 +99,6 @@ _See [config.lua#L9](./lua/avante/config.lua) for the full config_
|
|||||||
max_tokens = 4096,
|
max_tokens = 4096,
|
||||||
},
|
},
|
||||||
mappings = {
|
mappings = {
|
||||||
ask = "<leader>aa",
|
|
||||||
edit = "<leader>ae",
|
|
||||||
refresh = "<leader>ar",
|
|
||||||
--- @class AvanteConflictMappings
|
--- @class AvanteConflictMappings
|
||||||
diff = {
|
diff = {
|
||||||
ours = "co",
|
ours = "co",
|
||||||
@ -113,10 +115,6 @@ _See [config.lua#L9](./lua/avante/config.lua) for the full config_
|
|||||||
normal = "<CR>",
|
normal = "<CR>",
|
||||||
insert = "<C-s>",
|
insert = "<C-s>",
|
||||||
},
|
},
|
||||||
toggle = {
|
|
||||||
debug = "<leader>ad",
|
|
||||||
hint = "<leader>ah",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
hints = { enabled = true },
|
hints = { enabled = true },
|
||||||
windows = {
|
windows = {
|
||||||
@ -208,6 +206,11 @@ The following key bindings are available for use with `avante.nvim`:
|
|||||||
| <kbd>[</kbd><kbd>[</kbd> | jump to previous codeblocks (results window) |
|
| <kbd>[</kbd><kbd>[</kbd> | jump to previous codeblocks (results window) |
|
||||||
| <kbd>]</kbd><kbd>]</kbd> | jump to next codeblocks (results windows) |
|
| <kbd>]</kbd><kbd>]</kbd> | jump to next codeblocks (results windows) |
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
>
|
||||||
|
> If you are using `lazy.nvim`, then all keymap here will be safely set, meaning if `<leader>aa` is already binded, then avante.nvim won't bind this mapping.
|
||||||
|
> In this case, user will be responsible for setting up their own. See [notes on keymaps](https://github.com/yetone/avante.nvim/wiki#keymaps) for more details.
|
||||||
|
|
||||||
## Highlight Groups
|
## Highlight Groups
|
||||||
|
|
||||||
|
|
||||||
|
27
lua/avante/api.lua
Normal file
27
lua/avante/api.lua
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
local Utils = require("avante.utils")
|
||||||
|
|
||||||
|
---@class avante.ApiToggle
|
||||||
|
---@operator call(): boolean
|
||||||
|
---@field debug ToggleBind.wrap
|
||||||
|
---@field hint ToggleBind.wrap
|
||||||
|
---
|
||||||
|
---@class avante.Api
|
||||||
|
---@field ask fun(): boolean
|
||||||
|
---@field edit fun(): nil
|
||||||
|
---@field refresh fun(): nil
|
||||||
|
---@field toggle avante.ApiToggle
|
||||||
|
|
||||||
|
return setmetatable({}, {
|
||||||
|
__index = function(t, k)
|
||||||
|
local module = require("avante")
|
||||||
|
---@class AvailableApi: ApiCaller
|
||||||
|
---@field api? boolean
|
||||||
|
local has = module[k]
|
||||||
|
if type(has) ~= "table" or not has.api then
|
||||||
|
Utils.warn(k .. " is not a valid avante's API method", { once = true })
|
||||||
|
return
|
||||||
|
end
|
||||||
|
t[k] = has
|
||||||
|
return t[k]
|
||||||
|
end,
|
||||||
|
}) --[[@as avante.Api]]
|
@ -88,10 +88,7 @@ M.defaults = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mappings = {
|
mappings = {
|
||||||
ask = "<leader>aa",
|
---@class AvanteConflictMappings
|
||||||
edit = "<leader>ae",
|
|
||||||
refresh = "<leader>ar",
|
|
||||||
--- @class AvanteConflictMappings
|
|
||||||
diff = {
|
diff = {
|
||||||
ours = "co",
|
ours = "co",
|
||||||
theirs = "ct",
|
theirs = "ct",
|
||||||
@ -108,6 +105,10 @@ M.defaults = {
|
|||||||
normal = "<CR>",
|
normal = "<CR>",
|
||||||
insert = "<C-s>",
|
insert = "<C-s>",
|
||||||
},
|
},
|
||||||
|
-- NOTE: The following will be safely set by avante.nvim
|
||||||
|
ask = "<leader>aa",
|
||||||
|
edit = "<leader>ae",
|
||||||
|
refresh = "<leader>ar",
|
||||||
toggle = {
|
toggle = {
|
||||||
debug = "<leader>ad",
|
debug = "<leader>ad",
|
||||||
hint = "<leader>ah",
|
hint = "<leader>ah",
|
||||||
|
@ -26,7 +26,7 @@ H.commands = function()
|
|||||||
end
|
end
|
||||||
|
|
||||||
cmd("Ask", function()
|
cmd("Ask", function()
|
||||||
M.toggle()
|
M.ask()
|
||||||
end, { desc = "avante: ask AI for code suggestions" })
|
end, { desc = "avante: ask AI for code suggestions" })
|
||||||
cmd("Close", function()
|
cmd("Close", function()
|
||||||
local sidebar, _ = M._get()
|
local sidebar, _ = M._get()
|
||||||
@ -35,34 +35,53 @@ H.commands = function()
|
|||||||
end
|
end
|
||||||
sidebar:close()
|
sidebar:close()
|
||||||
end, { desc = "avante: close chat window" })
|
end, { desc = "avante: close chat window" })
|
||||||
|
cmd("Edit", function()
|
||||||
|
M.edit()
|
||||||
|
end, { desc = "avante: edit selected block" })
|
||||||
cmd("Refresh", function()
|
cmd("Refresh", function()
|
||||||
M.refresh()
|
M.refresh()
|
||||||
end, { desc = "avante: refresh windows" })
|
end, { desc = "avante: refresh windows" })
|
||||||
end
|
end
|
||||||
|
|
||||||
H.keymaps = function()
|
H.keymaps = function()
|
||||||
vim.keymap.set({ "n", "v" }, Config.mappings.ask, M.toggle, { noremap = true, desc = "avante: Ask" })
|
vim.keymap.set({ "n", "v" }, "<Plug>(AvanteAsk)", function()
|
||||||
vim.keymap.set("v", Config.mappings.edit, M.edit, { noremap = true, desc = "avante: Edit" })
|
M.ask()
|
||||||
vim.keymap.set("n", Config.mappings.refresh, M.refresh, { noremap = true, desc = "avante: Refresh" })
|
end, { noremap = true })
|
||||||
|
vim.keymap.set("v", "<Plug>(AvanteEdit)", function()
|
||||||
|
M.edit()
|
||||||
|
end, { noremap = true })
|
||||||
|
vim.keymap.set("n", "<Plug>(AvanteRefresh)", function()
|
||||||
|
M.refresh()
|
||||||
|
end, { noremap = true })
|
||||||
|
--- the following is kinda considered as internal mappings.
|
||||||
|
vim.keymap.set("n", "<Plug>(AvanteToggleDebug)", function()
|
||||||
|
M.toggle.debug()
|
||||||
|
end)
|
||||||
|
vim.keymap.set("n", "<Plug>(AvanteToggleHint)", function()
|
||||||
|
M.toggle.hint()
|
||||||
|
end)
|
||||||
|
|
||||||
Utils.toggle_map("n", Config.mappings.toggle.debug, {
|
Utils.safe_keymap_set({ "n", "v" }, Config.mappings.ask, "<Plug>(AvanteAsk)", { desc = "avante: ask" })
|
||||||
name = "debug",
|
Utils.safe_keymap_set("v", Config.mappings.edit, "<Plug>(AvanteEdit)", { desc = "avante: edit" })
|
||||||
get = function()
|
Utils.safe_keymap_set("n", Config.mappings.refresh, "<Plug>(AvanteRefresh)", { desc = "avante: refresh" })
|
||||||
return Config.debug
|
Utils.safe_keymap_set(
|
||||||
|
"n",
|
||||||
|
Config.mappings.toggle.debug,
|
||||||
|
"<Plug>(AvanteToggleDebug)",
|
||||||
|
{ desc = "avante: toggle debug" }
|
||||||
|
)
|
||||||
|
Utils.safe_keymap_set("n", Config.mappings.toggle.hint, "<Plug>(AvanteToggleHint)", { desc = "avante: toggle hint" })
|
||||||
|
end
|
||||||
|
|
||||||
|
---@class ApiCaller
|
||||||
|
---@operator call(...): any
|
||||||
|
|
||||||
|
H.api = function(fun)
|
||||||
|
return setmetatable({ api = true }, {
|
||||||
|
__call = function(...)
|
||||||
|
return fun(...)
|
||||||
end,
|
end,
|
||||||
set = function(state)
|
}) --[[@as ApiCaller]]
|
||||||
Config.override({ debug = state })
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
Utils.toggle_map("n", Config.mappings.toggle.hint, {
|
|
||||||
name = "hint",
|
|
||||||
get = function()
|
|
||||||
return Config.hints.enabled
|
|
||||||
end,
|
|
||||||
set = function(state)
|
|
||||||
Config.override({ hints = { enabled = state } })
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
H.signs = function()
|
H.signs = function()
|
||||||
@ -166,26 +185,55 @@ function M._init(id)
|
|||||||
return M
|
return M
|
||||||
end
|
end
|
||||||
|
|
||||||
M.toggle = function()
|
M.toggle = { api = true }
|
||||||
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()
|
M.toggle.debug = H.api(Utils.toggle_wrap({
|
||||||
end
|
name = "debug",
|
||||||
|
get = function()
|
||||||
|
return Config.debug
|
||||||
|
end,
|
||||||
|
set = function(state)
|
||||||
|
Config.override({ debug = state })
|
||||||
|
end,
|
||||||
|
}))
|
||||||
|
|
||||||
M.edit = function()
|
M.toggle.hint = H.api(Utils.toggle_wrap({
|
||||||
|
name = "hint",
|
||||||
|
get = function()
|
||||||
|
return Config.hints.enabled
|
||||||
|
end,
|
||||||
|
set = function(state)
|
||||||
|
Config.override({ hints = { enabled = state } })
|
||||||
|
end,
|
||||||
|
}))
|
||||||
|
|
||||||
|
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,
|
||||||
|
})
|
||||||
|
|
||||||
|
M.ask = H.api(function()
|
||||||
|
M.toggle()
|
||||||
|
end)
|
||||||
|
|
||||||
|
M.edit = H.api(function()
|
||||||
local _, selection = M._get()
|
local _, selection = M._get()
|
||||||
if not selection then
|
if not selection then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
selection:create_editing_input()
|
selection:create_editing_input()
|
||||||
end
|
end)
|
||||||
|
|
||||||
M.refresh = function()
|
M.refresh = H.api(function()
|
||||||
local sidebar, _ = M._get()
|
local sidebar, _ = M._get()
|
||||||
if not sidebar then
|
if not sidebar then
|
||||||
return
|
return
|
||||||
@ -213,7 +261,7 @@ M.refresh = function()
|
|||||||
sidebar.code.winid = curwin
|
sidebar.code.winid = curwin
|
||||||
sidebar.code.bufnr = curbuf
|
sidebar.code.bufnr = curbuf
|
||||||
sidebar:render()
|
sidebar:render()
|
||||||
end
|
end)
|
||||||
|
|
||||||
---@param opts? avante.Config
|
---@param opts? avante.Config
|
||||||
function M.setup(opts)
|
function M.setup(opts)
|
||||||
|
@ -69,23 +69,88 @@ M.shell_run = function(input_cmd)
|
|||||||
return { stdout = output, code = code }
|
return { stdout = output, code = code }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@see https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/util/toggle.lua
|
||||||
|
---
|
||||||
---@alias _ToggleSet fun(state: boolean): nil
|
---@alias _ToggleSet fun(state: boolean): nil
|
||||||
---@alias _ToggleGet fun(): boolean
|
---@alias _ToggleGet fun(): boolean
|
||||||
---
|
---
|
||||||
|
---@class ToggleBind
|
||||||
|
---@field name string
|
||||||
|
---@field set _ToggleSet
|
||||||
|
---@field get _ToggleGet
|
||||||
|
---
|
||||||
|
---@class ToggleBind.wrap: ToggleBind
|
||||||
|
---@operator call:boolean
|
||||||
|
|
||||||
|
---@param toggle ToggleBind
|
||||||
|
M.toggle_wrap = function(toggle)
|
||||||
|
return setmetatable(toggle, {
|
||||||
|
__call = function()
|
||||||
|
toggle.set(not toggle.get())
|
||||||
|
local state = toggle.get()
|
||||||
|
if state then
|
||||||
|
M.info("enabled: " .. toggle.name)
|
||||||
|
else
|
||||||
|
M.warn("disabled: " .. toggle.name)
|
||||||
|
end
|
||||||
|
return state
|
||||||
|
end,
|
||||||
|
}) --[[@as ToggleBind.wrap]]
|
||||||
|
end
|
||||||
|
|
||||||
---@param lhs string
|
---@param lhs string
|
||||||
---@param toggle {name: string, set: _ToggleSet, get: _ToggleGet}
|
---@param toggle ToggleBind
|
||||||
---@param mode? string | string[]
|
M.toggle_map = function(lhs, toggle)
|
||||||
M.toggle_map = function(mode, lhs, toggle)
|
M.safe_keymap_set("n", lhs, M.toggle_wrap(toggle), { desc = "toggle(avante): " .. toggle.name })
|
||||||
vim.keymap.set(mode or { "n" }, lhs, function()
|
end
|
||||||
toggle.set(not toggle.get())
|
|
||||||
local state = toggle.get()
|
-- Wrapper around vim.keymap.set that will
|
||||||
if state then
|
-- not create a keymap if a lazy key handler exists.
|
||||||
M.info("enabled: " .. toggle.name, { title = "Avante" })
|
-- It will also set `silent` to true by default.
|
||||||
else
|
--
|
||||||
M.warn("disabled: " .. toggle.name, { title = "Avante" })
|
---@param mode string|string[] Mode short-name, see |nvim_set_keymap()|.
|
||||||
|
--- Can also be list of modes to create mapping on multiple modes.
|
||||||
|
---@param lhs string Left-hand side |{lhs}| of the mapping.
|
||||||
|
---@param rhs string|function Right-hand side |{rhs}| of the mapping, can be a Lua function.
|
||||||
|
---
|
||||||
|
---@param opts? vim.keymap.set.Opts
|
||||||
|
---@see |nvim_set_keymap()|
|
||||||
|
---@see |maparg()|
|
||||||
|
---@see |mapcheck()|
|
||||||
|
---@see |mapset()|
|
||||||
|
M.safe_keymap_set = function(mode, lhs, rhs, opts)
|
||||||
|
---@type boolean
|
||||||
|
local ok
|
||||||
|
---@module "lazy.core.handler"
|
||||||
|
local H
|
||||||
|
|
||||||
|
ok, H = pcall(require, "lazy.core.handler")
|
||||||
|
if not ok then
|
||||||
|
M.warn("lazy.nvim is not available. Avante will use vim.keymap.set", { once = true })
|
||||||
|
vim.keymap.set(mode, lhs, rhs, opts)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local Keys = H.handlers.keys
|
||||||
|
---@cast Keys LazyKeysHandler
|
||||||
|
local modes = type(mode) == "string" and { mode } or mode
|
||||||
|
---@cast modes -string
|
||||||
|
|
||||||
|
---@param m string
|
||||||
|
modes = vim.tbl_filter(function(m)
|
||||||
|
return not (Keys.have and Keys:have(lhs, m))
|
||||||
|
end, modes)
|
||||||
|
|
||||||
|
-- don't create keymap if a lazy keys handler exists
|
||||||
|
if #modes > 0 then
|
||||||
|
opts = opts or {}
|
||||||
|
opts.silent = opts.silent ~= false
|
||||||
|
if opts.remap and not vim.g.vscode then
|
||||||
|
---@diagnostic disable-next-line: no-unknown
|
||||||
|
opts.remap = nil
|
||||||
end
|
end
|
||||||
return state
|
vim.keymap.set(mode, lhs, rhs, opts)
|
||||||
end, { desc = "toggle(avante): " .. toggle.name })
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param str string
|
---@param str string
|
||||||
|
Loading…
x
Reference in New Issue
Block a user