feat: floating input (#721)

* feat: add floating input to ask method

Open a floating input similar to the "edit" input for the "ask" input.
Enabled in config via `Config.windows.ask.floating` or by passing
`{ floating = true }` to the `api.ask` method.

Includes logic to ensure the sidebar uses the correct buffer and selection
if an existing sidebar is open for another code buffer.

Also refactored the `selection` module to extract the floating input
logic into a new `PromptInput` class.

* docs: update config options

* feat: more accurate annotations to prevent user misunderstandings

---------

Co-authored-by: yetone <yetoneful@gmail.com>
This commit is contained in:
Maddison Hellstrom
2024-10-14 20:22:34 -07:00
committed by GitHub
parent b19573cb2a
commit 964715be64
7 changed files with 443 additions and 286 deletions

View File

@@ -1,5 +1,6 @@
local Config = require("avante.config")
local Utils = require("avante.utils")
local PromptInput = require("avante.prompt_input")
---@class avante.ApiToggle
---@operator call(): boolean
@@ -88,6 +89,7 @@ end
---@field question? string optional questions
---@field win? table<string, any> windows options similar to |nvim_open_win()|
---@field ask? boolean
---@field floating? boolean whether to open a floating input to enter the question
---@param opts? AskOptions
M.ask = function(opts)
@@ -97,10 +99,42 @@ M.ask = function(opts)
opts = { question = opts }
end
if not require("avante").toggle_sidebar(opts) then return false end
if opts.question == nil or opts.question == "" then return true end
vim.api.nvim_exec_autocmds("User", { pattern = "AvanteInputSubmitted", data = { request = opts.question } })
return true
local has_question = opts.question ~= nil and opts.question ~= ""
if Utils.is_sidebar_buffer(0) and not has_question then
require("avante").close_sidebar()
return false
end
opts = vim.tbl_extend("force", { selection = Utils.get_visual_selection_and_range() }, opts)
local function ask(input)
if input == nil or input == "" then input = opts.question end
local sidebar = require("avante").get()
if sidebar and sidebar:is_open() and sidebar.code.bufnr ~= vim.api.nvim_get_current_buf() then
sidebar:close({ goto_code_win = false })
end
require("avante").open_sidebar(opts)
if input == nil or input == "" then return true end
vim.api.nvim_exec_autocmds("User", { pattern = "AvanteInputSubmitted", data = { request = input } })
return true
end
if opts.floating == true or (Config.windows.ask.floating == true and not has_question and opts.floating == nil) then
local prompt_input = PromptInput:new({
submit_callback = function(input) ask(input) end,
close_on_submit = true,
win_opts = {
border = Config.options.windows.ask.border,
title = { { "ask", "FloatTitle" } },
},
start_insert = Config.options.windows.ask.start_insert,
})
prompt_input:open()
return true
end
return ask()
end
---@param question? string