59497d6 introduced `sorters.fuzzy_with_index_bias`, which gives a
scoring boost to earlier entries.
However, this sorter relies on an `index` key existing for the entry, which is
only populated by the static finder currently. We should set it from the
other finders, too.
This will allow us to use said sorter everywhere. It will also let us
replicate the behaviour of `fzf --tiebreak=index`:
```
return pickers.new(opts, {
finder = finders.new_oneshot_job(...)
sorter = telescope.extensions.fzf.native_fzf_sorter(),
tiebreak = function(current_entry, existing_entry, _)
return current_entry.index < existing_entry.index
end
}):find()
```
This gives me better results for my "recently opened files" picker.
Other builtin pickers might benefit from this, too.
82 lines
1.7 KiB
Lua
82 lines
1.7 KiB
Lua
local async_job = require "telescope._"
|
|
local LinesPipe = require("telescope._").LinesPipe
|
|
|
|
local make_entry = require "telescope.make_entry"
|
|
local log = require "telescope.log"
|
|
|
|
return function(opts)
|
|
log.trace("Creating async_job:", opts)
|
|
local entry_maker = opts.entry_maker or make_entry.gen_from_string(opts)
|
|
|
|
local fn_command = function(prompt)
|
|
local command_list = opts.command_generator(prompt)
|
|
if command_list == nil then
|
|
return nil
|
|
end
|
|
|
|
local command = table.remove(command_list, 1)
|
|
|
|
local res = {
|
|
command = command,
|
|
args = command_list,
|
|
}
|
|
|
|
return res
|
|
end
|
|
|
|
local job
|
|
|
|
local callable = function(_, prompt, process_result, process_complete)
|
|
if job then
|
|
job:close(true)
|
|
end
|
|
|
|
local job_opts = fn_command(prompt)
|
|
if not job_opts then
|
|
return
|
|
end
|
|
|
|
local writer = nil
|
|
-- if job_opts.writer and Job.is_job(job_opts.writer) then
|
|
-- writer = job_opts.writer
|
|
if opts.writer then
|
|
error "async_job_finder.writer is not yet implemented"
|
|
writer = async_job.writer(opts.writer)
|
|
end
|
|
|
|
local stdout = LinesPipe()
|
|
|
|
job = async_job.spawn {
|
|
command = job_opts.command,
|
|
args = job_opts.args,
|
|
cwd = job_opts.cwd or opts.cwd,
|
|
env = job_opts.env or opts.env,
|
|
writer = writer,
|
|
|
|
stdout = stdout,
|
|
}
|
|
|
|
local line_num = 0
|
|
for line in stdout:iter(true) do
|
|
line_num = line_num + 1
|
|
local entry = entry_maker(line)
|
|
entry.index = line_num
|
|
if process_result(entry) then
|
|
return
|
|
end
|
|
end
|
|
|
|
process_complete()
|
|
end
|
|
|
|
return setmetatable({
|
|
close = function()
|
|
if job then
|
|
job:close(true)
|
|
end
|
|
end,
|
|
}, {
|
|
__call = callable,
|
|
})
|
|
end
|