feat: use regular floating win instead of nui.input (#191)

This commit is contained in:
yetone 2024-08-24 17:34:41 +08:00 committed by GitHub
parent b8b5a3086e
commit 0e07128b56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 43 additions and 110 deletions

View File

@ -15,6 +15,7 @@ api.nvim_set_hl(namespace, "FloatBorder", { link = "Normal" })
---@field on_mount_handlers table | nil ---@field on_mount_handlers table | nil
---@field on_unmount_handlers table | nil ---@field on_unmount_handlers table | nil
---@field augroup integer | nil ---@field augroup integer | nil
---@field keep_floating_style boolean | nil
local FloatingWindow = {} local FloatingWindow = {}
FloatingWindow.__index = FloatingWindow FloatingWindow.__index = FloatingWindow
@ -29,6 +30,7 @@ setmetatable(FloatingWindow, {
---@field buf_options? table<string, any> ---@field buf_options? table<string, any>
---@field win_options? table<string, any> ---@field win_options? table<string, any>
---@field float_options? table<string, any> ---@field float_options? table<string, any>
---@field keep_floating_style? boolean
---@param opts FloatingWindowOptions ---@param opts FloatingWindowOptions
---@return FloatingWindow ---@return FloatingWindow
@ -43,6 +45,7 @@ function FloatingWindow.new(opts)
instance.on_mount_handlers = {} instance.on_mount_handlers = {}
instance.on_unmount_handlers = {} instance.on_unmount_handlers = {}
instance.augroup = nil instance.augroup = nil
instance.keep_floating_style = opts.keep_floating_style or false
return instance return instance
end end
@ -55,8 +58,8 @@ function FloatingWindow.from_split_win(split_winid, opts)
local calc_floating_win_size = function(width, height) local calc_floating_win_size = function(width, height)
return { return {
width = math.max(width - 2, 0), width = math.max(width - 2, 1),
height = math.max(height - 3, 0), height = math.max(height - 3, 1),
} }
end end
@ -81,6 +84,7 @@ function FloatingWindow.from_split_win(split_winid, opts)
buf_options = buf_opts_, buf_options = buf_opts_,
win_options = win_opts_, win_options = win_opts_,
float_options = float_opts_, float_options = float_opts_,
keep_floating_style = opts.keep_floating_style,
}) })
floating_win:on_mount(function(winid) floating_win:on_mount(function(winid)
@ -178,7 +182,9 @@ function FloatingWindow:mount()
api.nvim_set_option_value(option, value, { win = self.winid }) api.nvim_set_option_value(option, value, { win = self.winid })
end end
if not self.keep_floating_style then
api.nvim_win_set_hl_ns(self.winid, namespace) api.nvim_win_set_hl_ns(self.winid, namespace)
end
for _, handler in ipairs(self.on_mount_handlers) do for _, handler in ipairs(self.on_mount_handlers) do
handler(self.winid, self.bufnr) handler(self.winid, self.bufnr)
@ -220,7 +226,7 @@ function FloatingWindow:on(event, handler, options)
}) })
end end
---@param mode string check `:h :map-modes` ---@param mode string|string[] check `:h :map-modes`
---@param key string|string[] key for the mapping ---@param key string|string[] key for the mapping
---@param handler string | fun(): nil handler for the mapping ---@param handler string | fun(): nil handler for the mapping
---@param opts? table<"'expr'"|"'noremap'"|"'nowait'"|"'remap'"|"'script'"|"'silent'"|"'unique'", boolean> ---@param opts? table<"'expr'"|"'noremap'"|"'nowait'"|"'remap'"|"'script'"|"'silent'"|"'unique'", boolean>

View File

@ -10,6 +10,8 @@ local M = {
REVERSED_NORMAL = "AvanteReversedNormal", REVERSED_NORMAL = "AvanteReversedNormal",
} }
M.input_ns = api.nvim_create_namespace("avante_input")
M.setup = function() M.setup = function()
local normal = api.nvim_get_hl(0, { name = "Normal" }) local normal = api.nvim_get_hl(0, { name = "Normal" })
api.nvim_set_hl(0, M.REVERSED_NORMAL, { fg = normal.bg }) api.nvim_set_hl(0, M.REVERSED_NORMAL, { fg = normal.bg })
@ -19,6 +21,10 @@ M.setup = function()
api.nvim_set_hl(0, M.REVERSED_SUBTITLE, { fg = "#56b6c2" }) api.nvim_set_hl(0, M.REVERSED_SUBTITLE, { fg = "#56b6c2" })
api.nvim_set_hl(0, M.THRIDTITLE, { fg = "#ABB2BF", bg = "#353B45" }) api.nvim_set_hl(0, M.THRIDTITLE, { fg = "#ABB2BF", bg = "#353B45" })
api.nvim_set_hl(0, M.REVERSED_THRIDTITLE, { fg = "#353B45" }) api.nvim_set_hl(0, M.REVERSED_THRIDTITLE, { fg = "#353B45" })
local normal_float = api.nvim_get_hl(0, { name = "NormalFloat" })
api.nvim_set_hl(M.input_ns, "NormalFloat", { fg = normal_float.fg, bg = normal_float.bg })
api.nvim_set_hl(M.input_ns, "FloatBorder", { fg = normal.fg, bg = normal.bg })
end end
return M return M

View File

@ -3,7 +3,6 @@ local fn = vim.fn
local Path = require("plenary.path") local Path = require("plenary.path")
local Split = require("nui.split") local Split = require("nui.split")
local Input = require("nui.input")
local event = require("nui.utils.autocmd").event local event = require("nui.utils.autocmd").event
local Config = require("avante.config") local Config = require("avante.config")
@ -637,71 +636,6 @@ function Sidebar:on_mount()
end, end,
}) })
local input_container_win_width = api.nvim_win_get_width(self.input_container.winid)
local input_container_win_height = api.nvim_win_get_height(self.input_container.winid)
api.nvim_create_autocmd("WinResized", {
group = self.augroup,
callback = function()
if
not self.input.winid
or not self.input_container.winid
or not api.nvim_win_is_valid(self.input.winid)
or not api.nvim_win_is_valid(self.input_container.winid)
then
return
end
local current_input_container_win_width = api.nvim_win_get_width(self.input_container.winid)
local current_input_container_win_height = api.nvim_win_get_height(self.input_container.winid)
if
current_input_container_win_width == input_container_win_width
and current_input_container_win_height == input_container_win_height
then
return
end
input_container_win_width = current_input_container_win_width
input_container_win_height = current_input_container_win_height
local old_floating_win_options = api.nvim_win_get_config(self.input.winid)
local new_floating_win_options = vim.tbl_deep_extend("force", old_floating_win_options, {
width = current_input_container_win_width - 2,
})
api.nvim_win_set_config(self.input.winid, new_floating_win_options)
end,
})
local input_win_width = api.nvim_win_get_width(self.input.winid)
local input_win_height = api.nvim_win_get_height(self.input.winid)
api.nvim_create_autocmd("WinResized", {
group = self.augroup,
callback = function()
if
not self.input.winid
or not self.input_container.winid
or not api.nvim_win_is_valid(self.input.winid)
or not api.nvim_win_is_valid(self.input_container.winid)
then
return
end
local current_input_win_width = api.nvim_win_get_width(self.input.winid)
local current_input_win_height = api.nvim_win_get_height(self.input.winid)
if current_input_win_width == input_win_width and current_input_win_height == input_win_height then
return
end
input_win_width = current_input_win_width
input_win_height = current_input_win_height
api.nvim_win_set_width(self.input_container.winid, input_win_width + 2)
end,
})
api.nvim_create_autocmd("WinClosed", { api.nvim_create_autocmd("WinClosed", {
group = self.augroup, group = self.augroup,
callback = function(args) callback = function(args)
@ -709,13 +643,6 @@ function Sidebar:on_mount()
if not self:is_focused_on(closed_winid) then if not self:is_focused_on(closed_winid) then
return return
end end
if closed_winid == self.winids.input then
-- Do not blame me for this hack: https://github.com/MunifTanjim/nui.nvim/blob/61574ce6e60c815b0a0c4b5655b8486ba58089a1/lua/nui/input/init.lua#L96-L99
---@diagnostic disable-next-line: undefined-field
if self.input._.pending_submit_value then
return
end
end
self:close() self:close()
end, end,
}) })
@ -873,7 +800,6 @@ function Sidebar:resize()
api.nvim_win_set_width(comp.winid, new_layout.width) api.nvim_win_set_width(comp.winid, new_layout.width)
end end
end end
self:create_input()
self:render_result_container() self:render_result_container()
self:render_input_container() self:render_input_container()
self:render_selected_code_container() self:render_selected_code_container()
@ -1129,7 +1055,6 @@ function Sidebar:get_commands()
---@diagnostic disable-next-line: unused-local ---@diagnostic disable-next-line: unused-local
callback = function(args, cb) callback = function(args, cb)
local help_text = get_help_text(items) local help_text = get_help_text(items)
self:create_input()
self:update_content(help_text, { focus = false, scroll = false }) self:update_content(help_text, { focus = false, scroll = false })
if cb then if cb then
cb(args) cb(args)
@ -1142,7 +1067,6 @@ function Sidebar:get_commands()
callback = function(args, cb) callback = function(args, cb)
local chat_history = {} local chat_history = {}
save_chat_history(self, chat_history) save_chat_history(self, chat_history)
self:create_input()
self:update_content("Chat history cleared", { focus = false, scroll = false }) self:update_content("Chat history cleared", { focus = false, scroll = false })
vim.defer_fn(function() vim.defer_fn(function()
self:close() self:close()
@ -1204,7 +1128,7 @@ function Sidebar:create_selected_code()
win_options = get_win_options(), win_options = get_win_options(),
position = "bottom", position = "bottom",
size = { size = {
height = selected_code_size, height = selected_code_size + 3,
}, },
}) })
self.selected_code_container:mount() self.selected_code_container:mount()
@ -1288,7 +1212,6 @@ function Sidebar:create_input()
return return
end end
else else
self:create_input()
self:update_content("Unknown command: " .. command, { focus = false, scroll = false }) self:update_content("Unknown command: " .. command, { focus = false, scroll = false })
return return
end end
@ -1331,7 +1254,6 @@ function Sidebar:create_input()
}) })
vim.defer_fn(function() vim.defer_fn(function()
self:create_input() -- Recreate input box
if self.result and self.result.winid and api.nvim_win_is_valid(self.result.winid) then if self.result and self.result.winid and api.nvim_win_is_valid(self.result.winid) then
api.nvim_set_current_win(self.result.winid) api.nvim_set_current_win(self.result.winid)
end end
@ -1370,33 +1292,30 @@ function Sidebar:create_input()
return return
end end
local win_width = api.nvim_win_get_width(self.input_container.winid) self.input = self:create_floating_window_for_split({
split_winid = self.input_container.winid,
buf_opts = {
modifiable = true,
},
keep_floating_style = true,
})
self.input = Input({ self.input:on_mount(function()
relative = { api.nvim_win_set_hl_ns(self.input.winid, Highlights.input_ns)
type = "win", end)
winid = self.input_container.winid,
}, local function on_submit()
position = { local lines = api.nvim_buf_get_lines(self.input.bufnr, 0, -1, false)
row = 2, local request = table.concat(lines, "\n")
col = 1, if request == "" then
},
size = {
width = win_width - 2, -- Subtract the width of the input box borders
},
}, {
disable_cursor_position_patch = true,
prompt = Config.windows.prompt.prefix,
default_value = " ",
on_submit = function(user_input)
user_input = Utils.trim_spaces(user_input)
if user_input == "" then
self:create_input()
return return
end end
handle_submit(user_input) api.nvim_buf_set_lines(self.input.bufnr, 0, -1, false, {})
end, handle_submit(request)
}) end
self.input:map("n", "<CR>", on_submit)
self.input:map("i", "<C-s>", on_submit)
self.input:mount() self.input:mount()
@ -1437,7 +1356,7 @@ function Sidebar:get_selected_code_size()
if self.code.selection ~= nil then if self.code.selection ~= nil then
local selected_code_lines = vim.split(self.code.selection.content, "\n") local selected_code_lines = vim.split(self.code.selection.content, "\n")
selected_code_lines_count = #selected_code_lines selected_code_lines_count = #selected_code_lines
selected_code_size = math.min(selected_code_lines_count, selected_code_max_lines_count) + 3 selected_code_size = math.min(selected_code_lines_count, selected_code_max_lines_count)
end end
return selected_code_size return selected_code_size
@ -1448,6 +1367,7 @@ end
---@field buf_opts table | nil ---@field buf_opts table | nil
---@field win_opts table | nil ---@field win_opts table | nil
---@field float_opts table | nil ---@field float_opts table | nil
---@field keep_floating_style boolean | nil
---@param opts CreateFloatingWindowForSplitOptions ---@param opts CreateFloatingWindowForSplitOptions
function Sidebar:create_floating_window_for_split(opts) function Sidebar:create_floating_window_for_split(opts)
@ -1492,7 +1412,7 @@ function Sidebar:render()
filetype = "Avante", filetype = "Avante",
}, },
float_opts = { float_opts = {
height = math.max(0, sidebar_height - selected_code_size - 9), height = math.max(1, sidebar_height - selected_code_size - 3 - 8),
}, },
}) })

View File

@ -265,6 +265,7 @@ function M.unlock_buf(bufnr)
end end
function M.lock_buf(bufnr) function M.lock_buf(bufnr)
vim.cmd("stopinsert")
vim.bo[bufnr].modified = false vim.bo[bufnr].modified = false
vim.bo[bufnr].modifiable = false vim.bo[bufnr].modifiable = false
end end