mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-05 03:08:13 +00:00
feat(picker): added support for item.resolve that gets called if needed during list rendering / preview
This commit is contained in:
parent
eb0e5b7efe
commit
b0d3266985
4 changed files with 37 additions and 3 deletions
|
@ -9,7 +9,7 @@ local Async = require("snacks.picker.util.async")
|
|||
local M = {}
|
||||
M.__index = M
|
||||
|
||||
---@alias snacks.picker.finder fun(opts:snacks.picker.Config, filter:snacks.picker.Filter): (snacks.picker.finder.Item[] | fun(cb:async fun(item:snacks.picker.finder.Item)))
|
||||
---@alias snacks.picker.finder fun(opts:snacks.picker.Config, filter:snacks.picker.Filter): (snacks.picker.finder.Item[] | fun(cb:async fun(item:snacks.picker.finder.Item), task:snacks.picker.Async))
|
||||
---@alias snacks.picker.finder.multi (snacks.picker.finder|string)[]
|
||||
|
||||
local YIELD_FIND = 1 -- ms
|
||||
|
@ -69,9 +69,10 @@ function M:run(picker)
|
|||
end
|
||||
|
||||
collectgarbage("stop") -- moar speed
|
||||
---@cast finder fun(cb:async fun(item:snacks.picker.finder.Item))
|
||||
---@cast finder fun(cb:async fun(item:snacks.picker.finder.Item), task:snacks.picker.Async)
|
||||
---@diagnostic disable-next-line: await-in-sync
|
||||
self.task = Async.new(function()
|
||||
local async = Async.running()
|
||||
---@async
|
||||
finder(function(item)
|
||||
if #self.items >= limit then
|
||||
|
@ -85,7 +86,7 @@ function M:run(picker)
|
|||
picker.matcher.task:resume()
|
||||
yield = yield or Async.yielder(YIELD_FIND)
|
||||
yield()
|
||||
end)
|
||||
end, async)
|
||||
end):on("done", function()
|
||||
collectgarbage("restart")
|
||||
picker.matcher.task:resume()
|
||||
|
|
|
@ -47,6 +47,7 @@ function M.new(picker)
|
|||
bo = { modifiable = false, filetype = "snacks_picker_list" },
|
||||
wo = {
|
||||
foldenable = false,
|
||||
foldmethod = "manual",
|
||||
cursorline = false,
|
||||
winhighlight = Snacks.picker.highlight.winhl("SnacksPickerList", { CursorLine = "Visual" }),
|
||||
},
|
||||
|
@ -329,6 +330,7 @@ end
|
|||
|
||||
---@param item snacks.picker.Item
|
||||
function M:format(item)
|
||||
Snacks.picker.util.resolve(item)
|
||||
-- Add selected and debug info
|
||||
local prefix = {} ---@type snacks.picker.Highlight[]
|
||||
if #self.selected > 0 or self.picker.opts.formatters.selected.show_always then
|
||||
|
|
|
@ -97,6 +97,7 @@ function M:show(picker)
|
|||
if self.item == item then
|
||||
return
|
||||
end
|
||||
Snacks.picker.util.resolve(item)
|
||||
self.item = item
|
||||
if item then
|
||||
local buf = self.win.buf
|
||||
|
|
|
@ -181,4 +181,34 @@ function M.parse(str)
|
|||
return t, args
|
||||
end
|
||||
|
||||
---@param item snacks.picker.Item
|
||||
function M.resolve(item)
|
||||
if item.resolve then
|
||||
item.resolve(item)
|
||||
item.resolve = nil
|
||||
end
|
||||
return item
|
||||
end
|
||||
|
||||
--- Returns the relative time from a given time
|
||||
--- as ... ago
|
||||
---@param time number in seconds
|
||||
function M.reltime(time)
|
||||
local delta = os.time() - time
|
||||
local tpl = {
|
||||
{ 1, 60, "just now", "just now" },
|
||||
{ 60, 3600, "a minute ago", "%d minutes ago" },
|
||||
{ 3600, 3600 * 24, "an hour ago", "%d hours ago" },
|
||||
{ 3600 * 24, 3600 * 24 * 7, "yesterday", "%d days ago" },
|
||||
{ 3600 * 24 * 7, 3600 * 24 * 7 * 4, "a week ago", "%d weeks ago" },
|
||||
}
|
||||
for _, v in ipairs(tpl) do
|
||||
if delta < v[2] then
|
||||
local value = math.floor(delta / v[1] + 0.5)
|
||||
return value == 1 and v[3] or v[4]:format(value)
|
||||
end
|
||||
end
|
||||
return os.date("%b %d, %Y", time) ---@type string
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue