mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-04 18:58:12 +00:00
perf(picker): dont use async when not needed
This commit is contained in:
parent
076feecf20
commit
6a523768cf
4 changed files with 30 additions and 10 deletions
|
@ -41,22 +41,27 @@ end
|
|||
|
||||
---@param picker snacks.Picker
|
||||
function M:run(picker)
|
||||
local score = require("snacks.picker.core.matcher").DEFAULT_SCORE
|
||||
self.task:abort()
|
||||
self.items = {}
|
||||
local yield ---@type fun()
|
||||
collectgarbage("stop") -- moar speed
|
||||
self.filter = picker.input.filter:clone({ trim = true })
|
||||
local finder = self._find(picker.opts, self.filter)
|
||||
local limit = picker.opts.limit or math.huge
|
||||
|
||||
-- PERF: if finder is a table, we can skip the async part
|
||||
if type(finder) == "table" then
|
||||
local items = finder --[[@as snacks.picker.finder.Item[] ]]
|
||||
finder = function(cb)
|
||||
for _, item in ipairs(items) do
|
||||
cb(item)
|
||||
end
|
||||
for i, item in ipairs(items) do
|
||||
item.idx, item.score = i, score
|
||||
self.items[i] = item
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
collectgarbage("stop") -- moar speed
|
||||
---@cast finder fun(cb:async fun(item:snacks.picker.finder.Item))
|
||||
---@diagnostic disable-next-line: await-in-sync
|
||||
self.task = Async.new(function()
|
||||
---@async
|
||||
finder(function(item)
|
||||
|
@ -67,7 +72,7 @@ function M:run(picker)
|
|||
end
|
||||
return
|
||||
end
|
||||
item.idx = #self.items + 1
|
||||
item.idx, item.score = #self.items + 1, score
|
||||
self.items[item.idx] = item
|
||||
picker.matcher.task:resume()
|
||||
yield = yield or Async.yielder(YIELD_FIND)
|
||||
|
|
|
@ -11,6 +11,8 @@ local Async = require("snacks.picker.util.async")
|
|||
---@field live? boolean
|
||||
local M = {}
|
||||
M.__index = M
|
||||
M.DEFAULT_SCORE = 1000
|
||||
M.INVERSE_SCORE = 1000
|
||||
|
||||
local YIELD_MATCH = 5 -- ms
|
||||
local clear = require("table.clear")
|
||||
|
@ -79,6 +81,14 @@ function M:run(picker, opts)
|
|||
if self.task:running() then
|
||||
return
|
||||
end
|
||||
|
||||
-- PERF: fast path for empty pattern
|
||||
if self:empty() then
|
||||
picker.list.items = picker.finder.items
|
||||
picker:update()
|
||||
return
|
||||
end
|
||||
|
||||
---@async
|
||||
self.task = Async.new(function()
|
||||
local yield = Async.yielder(YIELD_MATCH)
|
||||
|
@ -230,7 +240,7 @@ end
|
|||
function M:match(item, opts)
|
||||
opts = opts or {}
|
||||
if self:empty() or (self.live and not opts.force) then
|
||||
return 1000 -- empty pattern matches everything
|
||||
return M.DEFAULT_SCORE -- empty pattern matches everything
|
||||
end
|
||||
local score = 0
|
||||
local positions = opts.positions and {} or nil ---@type number[]?
|
||||
|
@ -288,7 +298,7 @@ function M:_match(item, mods, positions)
|
|||
if mods.field then
|
||||
if item[mods.field] == nil then
|
||||
if mods.inverse then
|
||||
return 1000
|
||||
return M.INVERSE_SCORE
|
||||
end
|
||||
return
|
||||
end
|
||||
|
@ -323,7 +333,7 @@ function M:_match(item, mods, positions)
|
|||
end
|
||||
if mods.inverse then
|
||||
if not from then
|
||||
return 1000
|
||||
return M.INVERSE_SCORE
|
||||
end
|
||||
return
|
||||
end
|
||||
|
|
|
@ -349,6 +349,7 @@ function M:update()
|
|||
end
|
||||
|
||||
local count = self.finder:count()
|
||||
local list_count = self.list:count()
|
||||
-- Check if we should show the picker
|
||||
if not self.shown then
|
||||
-- Always show live pickers
|
||||
|
@ -376,7 +377,7 @@ function M:update()
|
|||
self:show()
|
||||
self:debug("show")
|
||||
end
|
||||
elseif count > 1 or (count == 1 and not self.opts.auto_confirm) then -- show the picker if we have results
|
||||
elseif list_count > 1 or (list_count == 1 and not self.opts.auto_confirm) then -- show the picker if we have results
|
||||
self:show()
|
||||
self:debug("show")
|
||||
end
|
||||
|
|
|
@ -72,6 +72,10 @@ end
|
|||
---@param event snacks.picker.AsyncEvent
|
||||
---@param cb async fun(res:any, async:snacks.picker.Async)
|
||||
function Async:on(event, cb)
|
||||
if event == "done" and not self:running() then
|
||||
cb(nil, self)
|
||||
return self
|
||||
end
|
||||
self._on[event] = self._on[event] or {}
|
||||
table.insert(self._on[event], cb)
|
||||
return self
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue