mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-05 19:28:24 +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 = {}
|
local M = {}
|
||||||
M.__index = 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)[]
|
---@alias snacks.picker.finder.multi (snacks.picker.finder|string)[]
|
||||||
|
|
||||||
local YIELD_FIND = 1 -- ms
|
local YIELD_FIND = 1 -- ms
|
||||||
|
@ -69,9 +69,10 @@ function M:run(picker)
|
||||||
end
|
end
|
||||||
|
|
||||||
collectgarbage("stop") -- moar speed
|
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
|
---@diagnostic disable-next-line: await-in-sync
|
||||||
self.task = Async.new(function()
|
self.task = Async.new(function()
|
||||||
|
local async = Async.running()
|
||||||
---@async
|
---@async
|
||||||
finder(function(item)
|
finder(function(item)
|
||||||
if #self.items >= limit then
|
if #self.items >= limit then
|
||||||
|
@ -85,7 +86,7 @@ function M:run(picker)
|
||||||
picker.matcher.task:resume()
|
picker.matcher.task:resume()
|
||||||
yield = yield or Async.yielder(YIELD_FIND)
|
yield = yield or Async.yielder(YIELD_FIND)
|
||||||
yield()
|
yield()
|
||||||
end)
|
end, async)
|
||||||
end):on("done", function()
|
end):on("done", function()
|
||||||
collectgarbage("restart")
|
collectgarbage("restart")
|
||||||
picker.matcher.task:resume()
|
picker.matcher.task:resume()
|
||||||
|
|
|
@ -47,6 +47,7 @@ function M.new(picker)
|
||||||
bo = { modifiable = false, filetype = "snacks_picker_list" },
|
bo = { modifiable = false, filetype = "snacks_picker_list" },
|
||||||
wo = {
|
wo = {
|
||||||
foldenable = false,
|
foldenable = false,
|
||||||
|
foldmethod = "manual",
|
||||||
cursorline = false,
|
cursorline = false,
|
||||||
winhighlight = Snacks.picker.highlight.winhl("SnacksPickerList", { CursorLine = "Visual" }),
|
winhighlight = Snacks.picker.highlight.winhl("SnacksPickerList", { CursorLine = "Visual" }),
|
||||||
},
|
},
|
||||||
|
@ -329,6 +330,7 @@ end
|
||||||
|
|
||||||
---@param item snacks.picker.Item
|
---@param item snacks.picker.Item
|
||||||
function M:format(item)
|
function M:format(item)
|
||||||
|
Snacks.picker.util.resolve(item)
|
||||||
-- Add selected and debug info
|
-- Add selected and debug info
|
||||||
local prefix = {} ---@type snacks.picker.Highlight[]
|
local prefix = {} ---@type snacks.picker.Highlight[]
|
||||||
if #self.selected > 0 or self.picker.opts.formatters.selected.show_always then
|
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
|
if self.item == item then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
Snacks.picker.util.resolve(item)
|
||||||
self.item = item
|
self.item = item
|
||||||
if item then
|
if item then
|
||||||
local buf = self.win.buf
|
local buf = self.win.buf
|
||||||
|
|
|
@ -181,4 +181,34 @@ function M.parse(str)
|
||||||
return t, args
|
return t, args
|
||||||
end
|
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
|
return M
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue