Skip to content

Commit

Permalink
feat: introduce AsyncFinder
Browse files Browse the repository at this point in the history
  • Loading branch information
delphinus committed Aug 6, 2023
1 parent c107e22 commit 6084b95
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 27 deletions.
91 changes: 91 additions & 0 deletions lua/frecency/async_finder.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
local a = require "plenary.async"
local log = require "plenary.log"

---@class AsyncFinder: TelescopeFinder
---@field closed boolean
---@field entries FrecencyEntry[]
---@field rx { recv: fun(): table }
---@operator call():nil
local AsyncFinder = {}

---@param fs FrecencyFS
---@param path string
---@param entry_maker fun(file: FrecencyFile): FrecencyEntry
---@param initial_results FrecencyFile[]
---@return AsyncFinder
AsyncFinder.new = function(fs, path, entry_maker, initial_results)
local self = setmetatable({ closed = false, entries = {} }, {
__index = AsyncFinder,
__call = function(self, ...)
return self:_find(...)
end,
})
for i, file in ipairs(initial_results) do
local entry = entry_maker(file)
entry.index = i
table.insert(self.entries, entry)
end
local it = vim.F.nil_wrap(fs:scan_dir(path))
local index = #initial_results
local count = 0
local tx, rx = a.control.channel.mpsc()
self.rx = rx
a.run(function()
for name in it do
if self.closed then
break
end
index = index + 1
count = count + 1
---@diagnostic disable-next-line: missing-fields
local entry = entry_maker { path = vim.fs.joinpath(path, name), score = 0 }
if entry then
entry.index = index
table.insert(self.entries, entry)
tx.send(entry)
if count % 1000 == 0 then
a.util.sleep(0)
end
end
end
self:close()
tx.send(nil)
end)
return self
end

---@param prompt string
---@param process_result fun(entry: FrecencyEntry): nil
---@param process_complete fun(): nil
function AsyncFinder:_find(prompt, process_result, process_complete)
for _, entry in ipairs(self.entries) do
if process_result(entry) then
return
end
end
local count = 0
local last_index = self.entries[#self.entries].index
while true do
if self.closed then
break
end
local entry = self.rx.recv()
if entry then
if entry.index > last_index then
if process_result(entry) then
return
end
count = count + 1
end
else
break
end
end
process_complete()
end

function AsyncFinder:close()
self.closed = true
end

return AsyncFinder
29 changes: 2 additions & 27 deletions lua/frecency/finder.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local AsyncFinder = require "frecency.async_finder"
local finders = require "telescope.finders"
local log = require "plenary.log"

Expand Down Expand Up @@ -39,33 +40,7 @@ function Finder:start(filepath_formatter, initial_results, opts)
}
end
log.debug { finder = opts }
return finders.new_dynamic { entry_maker = entry_maker, fn = self:create_fn(initial_results, opts.workspace) }
end

---@private
---@param initial_results table
---@param path string
---@return fun(prompt: string?): table[]
function Finder:create_fn(initial_results, path)
local it = vim.F.nil_wrap(self.fs:scan_dir(path))
local results = vim.deepcopy(initial_results)
local called = 0
---@param _ string?
---@return table[]
return function(_)
called = called + 1
log.debug { called = called }
local count = 0
for name in it do
table.insert(results, { path = vim.fs.joinpath(path, name), score = 0 })
count = count + 1
if count >= self.config.chunk_size then
break
end
end
log.debug(("dynamic results: %d"):format(#results))
return results
end
return AsyncFinder.new(self.fs, opts.workspace, entry_maker, initial_results)
end

return Finder

0 comments on commit 6084b95

Please sign in to comment.