Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 60 additions & 13 deletions lua/telescope/finders.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
local Job = require('plenary.job')

local co = coroutine
local utils = require('telescope.utils')
local make_entry = require('telescope.make_entry')
local Executor = require('telescope.utils').Executor
local log = require('telescope.log')

local finders = {}
Expand All @@ -14,6 +17,58 @@ local _callable_obj = function()
return obj
end

local static_find
do
local exe = Executor.new {}
static_find = function(results, process_result, process_complete)
if #exe.tasks ~= 0 then
exe:close()
end
exe:add(co.create(function(results)
for _, v in ipairs(results) do
process_result(v)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing we can do is also check the result of process_result or similar to determine if we should stop the execution.

co.yield()
end
process_complete()
end), results)

exe:run()
end
end

local static_find_no_cancel = function(results, process_result, process_complete)
local exe = Executor.new {}
exe:add(co.create(function()
for _, v in ipairs(results) do
process_result(v)
co.yield()
end
process_complete()
end))
end

local job_find
do
local exe = Executor.new {}
job_find = function(results, process_result, process_complete, current_count, completed)
if #exe.tasks ~= 0 then
exe:close()
end

exe:add(co.create(function(results)
for index = 1, current_count do
process_result(results[index])
co.yield()
end

if completed then
process_complete()
end
end), results)

exe:run()
end
end

--[[ =============================================================

Expand All @@ -33,7 +88,7 @@ local JobFinder = _callable_obj()
function JobFinder:new(opts)
opts = opts or {}

> assert(not opts.results, "`results` should be used with finder.new_table")
assert(not opts.results, "`results` should be used with finder.new_table")
assert(not opts.static, "`static` should be used with finder.new_oneshot_job")

local obj = setmetatable({
Expand Down Expand Up @@ -177,15 +232,11 @@ function OneshotJobFinder:new(opts)
while true do
finder, _, process_result, process_complete = coroutine.yield()
num_execution = num_execution + 1

local current_count = num_results
for index = 1, current_count do
process_result(results[index])
end

if completed then
process_complete()
end
-- static_find(results, process_result, process_complete)
-- static_find_no_cancel(results, process_result, process_complete)
job_find(results, process_result, process_complete, current_count, completed)
end
end)

Expand Down Expand Up @@ -249,11 +300,7 @@ function StaticFinder:new(opts)
end

function StaticFinder:_find(_, process_result, process_complete)
for _, v in ipairs(self.results) do
process_result(v)
end

process_complete()
static_find(self.results, process_result, process_complete)
end


Expand Down
1 change: 1 addition & 0 deletions lua/telescope/pickers.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local a = vim.api
local co = coroutine
local popup = require('popup')

require('telescope')
Expand Down
165 changes: 165 additions & 0 deletions lua/telescope/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,169 @@ function utils.get_os_command_output(cmd)
return Job:new({ command = command, args = cmd }):sync()
end

local uv = vim.loop
local co = coroutine

local Executor = {}
Executor.__index = Executor

function Executor.new(opts)
opts = opts or {}

local self = setmetatable({}, Executor)

self.tasks = opts.tasks or {}
self.mode = opts.mode or "next"
self.index = opts.start_idx or 1
self.idle = uv.new_idle()

return self
end

function Executor:run()
self.idle:start(vim.schedule_wrap(function()
if #self.tasks == 0 then
self.idle:stop()
return
end

if self.mode == "finish" then
self:step_finish()
else
self:step()
end
end))
end

function Executor:close()
self.idle:stop()
self.tasks = {}
end

function Executor:step_finish()
if #self.tasks == 0 then return end
local curr_task = self.tasks[self.index]
if curr_task == nil then
self.index = 1
curr_task = self.tasks[self.index]
end

local _, _ = co.resume(curr_task)
if co.status(curr_task) == "dead" then
table.remove(self.tasks, self.index)

self.index = self.index + 1
end
end

function Executor:step()
if #self.tasks == 0 then return end
local curr_task = self.tasks[self.index]
if curr_task == nil then
self.index = 1
curr_task = self.tasks[self.index]
end

local _, _ = co.resume(curr_task[1], unpack(curr_task[2]))
if co.status(curr_task[1]) == "dead" then
table.remove(self.tasks, self.index)
end

self.index = self.index + 1
end

function Executor:get_current_task()
return self.tasks[self.index]
end

function Executor:remove_task(idx)
table.remove(self.tasks, idx)
end

function Executor:add(task, ...)
table.insert(self.tasks, {task, {...}})
end

utils.Executor = Executor

List = {}

function List.new()
return {first = 0, last = -1}
end

function List.pushleft(list, value)
local first = list.first - 1
list.first = first
list[first] = value
end

function List.pushright (list, value)
local last = list.last + 1
list.last = last
list[last] = value
end

function List.popleft (list)
local first = list.first
if first > list.last then return nil end
local value = list[first]
list[first] = nil -- to allow garbage collection
list.first = first + 1
return value
end

function List.is_empty(list)
return list.first > list.last
end

function List.popright (list)
local last = list.last
if list.first > last then return nil end
local value = list[last]
list[last] = nil -- to allow garbage collection
list.last = last - 1
return value
end

function List.len(list)
return list.last - list.first
end

utils.List = List

function successive_async(f)
local list = List.new()

local function wrapped(...)
if list == nil then return end
-- if List.is_empty(list) or list == nil then return end

List.pushleft(list, {...})
local curr = List.popright(list)
f(unpack(curr))
end

local function finish()
list = nil
end

return wrapped
end

function utils.exe_cancel_wrap(fn)
local exe = Executor.new {}
exe:add(fn)

local function wrapped(...)
print(#{...})
exe.idle:stop()
exe.tasks[1][1] = fn
exe.tasks[1][2] = {...}
exe:run()
end

return wrapped
end

return utils