feat(input): persistent history. Closes #591

This commit is contained in:
Folke Lemaitre 2025-01-20 18:31:10 +01:00
parent ea665ebad1
commit 0ed68bdf72
No known key found for this signature in database
GPG key ID: 41F8B1FBACAE2040

View file

@ -86,27 +86,33 @@ local ui_input = vim.ui.input
---@field win? snacks.win ---@field win? snacks.win
local ctx = {} local ctx = {}
local history = {} ---@type string[]
---@param opts? snacks.input.Opts ---@param opts? snacks.input.Opts
---@param on_confirm fun(value?: string) ---@param on_confirm fun(value?: string)
function M.input(opts, on_confirm) function M.input(opts, on_confirm)
assert(type(on_confirm) == "function", "`on_confirm` must be a function") assert(type(on_confirm) == "function", "`on_confirm` must be a function")
local history = require("snacks.picker.util.history").new("input", {
filter = function(value)
return value ~= ""
end,
})
local parent_win = vim.api.nvim_get_current_win() local parent_win = vim.api.nvim_get_current_win()
local mode = vim.fn.mode() local mode = vim.fn.mode()
local hist_idx = #history + 1 ---@param force? boolean
local hist_cursor = hist_idx local function record(force)
local function record()
if not ctx.win then if not ctx.win then
return return
end end
local text = ctx.win:text() if not force and not history:is_current() then
if text and not text:find("^%s*$") then return
history[hist_idx] = text
end end
local text = vim.trim(ctx.win:text())
if text == "" then
return
end
history:record(text)
end end
local function confirm(value) local function confirm(value)
@ -148,7 +154,9 @@ function M.input(opts, on_confirm)
table.insert(title, { " " }) table.insert(title, { " " })
end end
---@param text? string
local function set(text) local function set(text)
text = text or ""
vim.api.nvim_buf_set_lines(ctx.win.buf, 0, -1, false, { text }) vim.api.nvim_buf_set_lines(ctx.win.buf, 0, -1, false, { text })
vim.api.nvim_win_set_cursor(ctx.win.win, { 1, #text }) vim.api.nvim_win_set_cursor(ctx.win.win, { 1, #text })
end end
@ -177,18 +185,12 @@ function M.input(opts, on_confirm)
self:close() self:close()
end, end,
hist_up = function(self) hist_up = function(self)
if hist_idx == hist_cursor then record()
record() set(history:prev())
end
hist_cursor = math.max(hist_cursor - 1, 1)
set(history[hist_cursor] or "")
end, end,
hist_down = function(self) hist_down = function(self)
if hist_idx == hist_cursor then record()
record() set(history:next())
end
hist_cursor = math.min(hist_cursor + 1, hist_idx)
set(history[hist_cursor] or "")
end, end,
cmp = function() cmp = function()
return vim.fn.pumvisible() == 0 and "<c-x><c-u>" return vim.fn.pumvisible() == 0 and "<c-x><c-u>"