fix(ui): use dressing.nvim for better input support (#58)
* fix(ui): use dressing.nvim for better input support Signed-off-by: Aaron Pham <contact@aarnphm.xyz> * chore: add small docs on setting up dependencies Signed-off-by: Aaron Pham <contact@aarnphm.xyz> * chore: update docs Signed-off-by: Aaron Pham <contact@aarnphm.xyz> * revert: add back quick docs for setup Signed-off-by: Aaron Pham <contact@aarnphm.xyz> * chore: update readme Signed-off-by: Aaron Pham <contact@aarnphm.xyz> * Update lua/avante/ui/dressing.lua * Update lua/avante/ui/dressing.lua --------- Signed-off-by: Aaron Pham <contact@aarnphm.xyz>
This commit is contained in:
parent
8e503ef114
commit
58af2b7f92
10
README.md
10
README.md
@ -25,18 +25,22 @@ Install `avante.nvim` using [lazy.nvim](https://github.com/folke/lazy.nvim):
|
|||||||
{
|
{
|
||||||
"yetone/avante.nvim",
|
"yetone/avante.nvim",
|
||||||
event = "VeryLazy",
|
event = "VeryLazy",
|
||||||
opts = {},
|
|
||||||
build = "make",
|
build = "make",
|
||||||
|
opts = {
|
||||||
|
-- add any opts here
|
||||||
|
},
|
||||||
dependencies = {
|
dependencies = {
|
||||||
"nvim-tree/nvim-web-devicons",
|
"nvim-tree/nvim-web-devicons",
|
||||||
|
"stevearc/dressing.nvim",
|
||||||
|
"nvim-lua/plenary.nvim",
|
||||||
{
|
{
|
||||||
"grapp-dev/nui-components.nvim",
|
"grapp-dev/nui-components.nvim",
|
||||||
dependencies = {
|
dependencies = {
|
||||||
"MunifTanjim/nui.nvim"
|
"MunifTanjim/nui.nvim"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nvim-lua/plenary.nvim",
|
--- The below is optional, make sure to setup it properly if you have lazy=true
|
||||||
{ -- Optional
|
{
|
||||||
'MeanderingProgrammer/render-markdown.nvim',
|
'MeanderingProgrammer/render-markdown.nvim',
|
||||||
opts = {
|
opts = {
|
||||||
file_types = { "markdown", "Avante" },
|
file_types = { "markdown", "Avante" },
|
||||||
|
@ -2,8 +2,6 @@ local fn = vim.fn
|
|||||||
local api = vim.api
|
local api = vim.api
|
||||||
|
|
||||||
local curl = require("plenary.curl")
|
local curl = require("plenary.curl")
|
||||||
local Input = require("nui.input")
|
|
||||||
local Event = require("nui.utils.autocmd").event
|
|
||||||
|
|
||||||
local Utils = require("avante.utils")
|
local Utils = require("avante.utils")
|
||||||
local Config = require("avante.config")
|
local Config = require("avante.config")
|
||||||
@ -30,43 +28,6 @@ E = setmetatable(E, {
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- courtesy of https://github.com/MunifTanjim/nui.nvim/wiki/nui.input
|
|
||||||
local SecretInput = Input:extend("SecretInput")
|
|
||||||
|
|
||||||
function SecretInput:init(popup_options, options)
|
|
||||||
assert(
|
|
||||||
not options.conceal_char or vim.api.nvim_strwidth(options.conceal_char) == 1,
|
|
||||||
"conceal_char must be a single char"
|
|
||||||
)
|
|
||||||
|
|
||||||
popup_options.win_options = vim.tbl_deep_extend("force", popup_options.win_options or {}, {
|
|
||||||
conceallevel = 2,
|
|
||||||
concealcursor = "nvi",
|
|
||||||
})
|
|
||||||
|
|
||||||
SecretInput.super.init(self, popup_options, options)
|
|
||||||
|
|
||||||
self._.conceal_char = type(options.conceal_char) == "nil" and "*" or options.conceal_char
|
|
||||||
end
|
|
||||||
|
|
||||||
function SecretInput:mount()
|
|
||||||
SecretInput.super.mount(self)
|
|
||||||
|
|
||||||
local conceal_char = self._.conceal_char
|
|
||||||
local prompt_length = vim.api.nvim_strwidth(vim.fn.prompt_getprompt(self.bufnr))
|
|
||||||
|
|
||||||
vim.api.nvim_buf_call(self.bufnr, function()
|
|
||||||
vim.cmd(string.format(
|
|
||||||
[[
|
|
||||||
syn region SecretValue start=/^/ms=s+%s end=/$/ contains=SecretChar
|
|
||||||
syn match SecretChar /./ contained conceal %s
|
|
||||||
]],
|
|
||||||
prompt_length,
|
|
||||||
conceal_char and "cchar=" .. (conceal_char or "*") or ""
|
|
||||||
))
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- return the environment variable name for the given provider
|
--- return the environment variable name for the given provider
|
||||||
---@param provider? Provider
|
---@param provider? Provider
|
||||||
---@return string the envvar key
|
---@return string the envvar key
|
||||||
@ -78,45 +39,29 @@ E.key = function(provider)
|
|||||||
end
|
end
|
||||||
|
|
||||||
E.setup = function(var)
|
E.setup = function(var)
|
||||||
|
local Dressing = require("avante.ui.dressing")
|
||||||
|
|
||||||
if E._once then
|
if E._once then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local input = SecretInput({
|
---@param value string
|
||||||
position = "50%",
|
---@return nil
|
||||||
size = {
|
local function on_confirm(value)
|
||||||
width = 40,
|
if value then
|
||||||
},
|
|
||||||
border = {
|
|
||||||
style = "single",
|
|
||||||
text = {
|
|
||||||
top = "Enter " .. var,
|
|
||||||
top_align = "center",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
win_options = {
|
|
||||||
winhighlight = "Normal:Normal,FloatBorder:Normal",
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
prompt = "> ",
|
|
||||||
default_value = "",
|
|
||||||
on_submit = function(value)
|
|
||||||
vim.fn.setenv(var, value)
|
vim.fn.setenv(var, value)
|
||||||
end,
|
E._once = true
|
||||||
on_close = function()
|
else
|
||||||
if not E[Config.provider] then
|
if not E[Config.provider] then
|
||||||
vim.notify_once("Failed to set " .. var .. ". Avante won't work as expected", vim.log.levels.WARN)
|
vim.notify_once("Failed to set " .. var .. ". Avante won't work as expected", vim.log.levels.WARN)
|
||||||
end
|
end
|
||||||
end,
|
end
|
||||||
})
|
end
|
||||||
|
|
||||||
api.nvim_create_autocmd({ "BufEnter", "BufWinEnter" }, {
|
api.nvim_create_autocmd({ "BufEnter", "BufWinEnter" }, {
|
||||||
pattern = "*",
|
pattern = "*",
|
||||||
|
once = true,
|
||||||
callback = function()
|
callback = function()
|
||||||
if E._once then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.defer_fn(function()
|
vim.defer_fn(function()
|
||||||
-- only mount if given buffer is not of buftype ministarter, dashboard, alpha, qf
|
-- only mount if given buffer is not of buftype ministarter, dashboard, alpha, qf
|
||||||
local exclude_buftypes = { "dashboard", "alpha", "qf", "nofile" }
|
local exclude_buftypes = { "dashboard", "alpha", "qf", "nofile" }
|
||||||
@ -135,20 +80,11 @@ E.setup = function(var)
|
|||||||
not vim.tbl_contains(exclude_buftypes, vim.bo.buftype)
|
not vim.tbl_contains(exclude_buftypes, vim.bo.buftype)
|
||||||
and not vim.tbl_contains(exclude_filetypes, vim.bo.filetype)
|
and not vim.tbl_contains(exclude_filetypes, vim.bo.filetype)
|
||||||
then
|
then
|
||||||
E._once = true
|
Dressing.initialize_input_buffer({ opts = { prompt = "Enter " .. var .. ": " }, on_confirm = on_confirm })
|
||||||
input:mount()
|
|
||||||
end
|
end
|
||||||
end, 200)
|
end, 200)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
input:map("n", "<Esc>", function()
|
|
||||||
input:unmount()
|
|
||||||
end, { noremap = true })
|
|
||||||
|
|
||||||
input:on(Event.BufLeave, function()
|
|
||||||
input:unmount()
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local system_prompt = [[
|
local system_prompt = [[
|
||||||
|
@ -525,20 +525,20 @@ function M.setup()
|
|||||||
|
|
||||||
set_plug_mappings()
|
set_plug_mappings()
|
||||||
|
|
||||||
api.nvim_create_augroup(AUGROUP_NAME, { clear = true })
|
local augroup = api.nvim_create_augroup(AUGROUP_NAME, { clear = true })
|
||||||
api.nvim_create_autocmd("ColorScheme", {
|
api.nvim_create_autocmd("ColorScheme", {
|
||||||
group = AUGROUP_NAME,
|
group = augroup,
|
||||||
callback = function()
|
callback = function()
|
||||||
set_highlights(Config.diff.highlights)
|
set_highlights(Config.diff.highlights)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
api.nvim_create_autocmd("User", {
|
api.nvim_create_autocmd("User", {
|
||||||
group = AUGROUP_NAME,
|
group = augroup,
|
||||||
pattern = "AvanteConflictDetected",
|
pattern = "AvanteConflictDetected",
|
||||||
callback = function()
|
callback = function()
|
||||||
local bufnr = api.nvim_get_current_buf()
|
local bufnr = api.nvim_get_current_buf()
|
||||||
vim.diagnostic.enable(not vim.diagnostic.is_enabled(), { bufnr = bufnr })
|
vim.diagnostic.enable(false, { bufnr = bufnr })
|
||||||
setup_buffer_mappings(bufnr)
|
setup_buffer_mappings(bufnr)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
@ -548,7 +548,7 @@ function M.setup()
|
|||||||
pattern = "AvanteConflictResolved",
|
pattern = "AvanteConflictResolved",
|
||||||
callback = function()
|
callback = function()
|
||||||
local bufnr = api.nvim_get_current_buf()
|
local bufnr = api.nvim_get_current_buf()
|
||||||
vim.diagnostic.enable(not vim.diagnostic.is_enabled(), { bufnr = bufnr })
|
vim.diagnostic.enable(true, { bufnr = bufnr })
|
||||||
clear_buffer_mappings(bufnr)
|
clear_buffer_mappings(bufnr)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
62
lua/avante/ui/dressing.lua
Normal file
62
lua/avante/ui/dressing.lua
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
local api, fn = vim.api, vim.fn
|
||||||
|
|
||||||
|
---@class avante.Dressing
|
||||||
|
local H = {}
|
||||||
|
|
||||||
|
local C = {
|
||||||
|
filetype = "DressingInput",
|
||||||
|
conceal_char = "*",
|
||||||
|
close_window = function()
|
||||||
|
require("dressing.input").close()
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
---@class avante.DressingState
|
||||||
|
local state = {
|
||||||
|
winid = nil, ---@type integer
|
||||||
|
input_winid = nil, ---@type integer
|
||||||
|
input_bufnr = nil, ---@type integer
|
||||||
|
}
|
||||||
|
|
||||||
|
---@param options {opts: table<string, any>, on_confirm: fun(value: string): nil} See vim.ui.input for more info
|
||||||
|
H.initialize_input_buffer = function(options)
|
||||||
|
state.winid = api.nvim_get_current_win()
|
||||||
|
vim.ui.input(vim.tbl_deep_extend("force", { default = "" }, options.opts), options.on_confirm)
|
||||||
|
for _, winid in ipairs(api.nvim_list_wins()) do
|
||||||
|
local bufnr = api.nvim_win_get_buf(winid)
|
||||||
|
if vim.bo[bufnr].filetype == C.filetype then
|
||||||
|
state.input_winid = winid
|
||||||
|
state.input_bufnr = bufnr
|
||||||
|
vim.wo[winid].conceallevel = 2
|
||||||
|
vim.wo[winid].concealcursor = "nvi"
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local prompt_length = api.nvim_strwidth(fn.prompt_getprompt(state.input_bufnr))
|
||||||
|
api.nvim_buf_call(state.input_bufnr, function()
|
||||||
|
vim.cmd(string.format(
|
||||||
|
[[
|
||||||
|
syn region SecretValue start=/^/ms=s+%s end=/$/ contains=SecretChar
|
||||||
|
syn match SecretChar /./ contained conceal %s
|
||||||
|
]],
|
||||||
|
prompt_length,
|
||||||
|
"cchar=*"
|
||||||
|
))
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param switch_buffer? boolean To switch back original buffer, default to tru
|
||||||
|
H.teardown = function(switch_buffer)
|
||||||
|
switch_buffer = switch_buffer or true
|
||||||
|
|
||||||
|
if state.input_winid and api.nvim_win_is_valid(state.input_winid) then
|
||||||
|
C.close_window()
|
||||||
|
state.input_winid = nil
|
||||||
|
if switch_buffer then
|
||||||
|
pcall(api.nvim_set_current_win, state.winid)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return H
|
Loading…
x
Reference in New Issue
Block a user