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 5, 2023
1 parent b88280a commit 42c3e70
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 97 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
32 changes: 2 additions & 30 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 @@ -42,36 +43,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
self.need_refresh = true
---@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
log.debug(("dynamic results: %d"):format(#results))
return results
end
end
self.need_refresh = false
log.debug(("dynamic results: %d"):format(#results))
return results
end
return AsyncFinder.new(self.fs, opts.workspace, entry_maker, initial_results)
end

return Finder
Empty file added lua/frecency/fs_finder.lua
Empty file.
22 changes: 13 additions & 9 deletions lua/frecency/picker.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
local Controller = require "frecency.picker.controller"
local log = require "plenary.log"
local Path = require "plenary.path" --[[@as PlenaryPath]]
local actions = require "telescope.actions"
Expand Down Expand Up @@ -101,7 +100,8 @@ function Picker:start(opts)
return self:attach_mappings(prompt_bufnr)
end,
})
Controller.new(picker, self.finder):start()
picker:find()
self:set_prompt_options(picker.prompt_bufnr)
end

function Picker:discard_results()
Expand Down Expand Up @@ -241,15 +241,9 @@ function Picker:on_input_filter_cb(picker_opts)
if self.workspace ~= workspace then
self.workspace = workspace
self.results = self:fetch_results(workspace)
local need_scandir = self.workspace and self.config.show_unindexed and true or false
if need_scandir then
self:set_updater()
else
self:remove_updater()
end
opts.updated_finder = self.finder:start(filepath_formatter, self.results, {
initial_results = self.results,
need_scandir = need_scandir,
need_scandir = self.workspace and self.config.show_unindexed and true or false,
workspace = self.workspace,
workspace_tag = tag,
})
Expand Down Expand Up @@ -292,4 +286,14 @@ function Picker:filepath_formatter(picker_opts)
end
end

---@private
---@param bufnr integer
---@return nil
function Picker:set_prompt_options(bufnr)
vim.bo[bufnr].filetype = "frecency"
vim.bo[bufnr].completefunc = "v:lua.require'telescope'.extensions.frecency.complete"
vim.keymap.set("i", "<Tab>", "pumvisible() ? '<C-n>' : '<C-x><C-u>'", { buffer = bufnr, expr = true })
vim.keymap.set("i", "<S-Tab>", "pumvisible() ? '<C-p>' : ''", { buffer = bufnr, expr = true })
end

return Picker
58 changes: 0 additions & 58 deletions lua/frecency/picker/controller.lua

This file was deleted.

0 comments on commit 42c3e70

Please sign in to comment.